theory SergotTheorems

imports Main Sergot

begin

lemma Superadditivity: "G \<subseteq> H \<longrightarrow> \<lfloor>(\<^bold>[G\<^bold>]\<phi>) \<^bold>\<rightarrow> (\<^bold>[H\<^bold>]\<phi>)\<rfloor>" by auto
(*To add: s5 stuff*)

lemma IntEmptyBox: "(\<not> (\<exists>x. (x \<in> G \<inter> H))) \<longrightarrow> \<lfloor>(\<^bold>[G\<^bold>]\<^bold>[H\<^bold>]\<phi>) \<^bold>\<rightarrow> \<^bold>\<box>\<phi>\<rfloor>"
  oops (*nitpick finds counterexample*)

lemma helper1: "\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub>H \<phi>) \<longrightarrow> H \<subseteq> G \<longrightarrow> \<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub>H \<phi>)" by blast

lemma helper2: "(\<tau> \<^bold>\<Turnstile> (\<^bold>[G\<^bold>]\<phi>)) \<longrightarrow> (\<exists>H\<subseteq>G. (\<not> (\<exists>K\<subset>H. (\<^bold>[K\<^bold>]\<phi>) \<tau>)))" by blast

lemma NessCompHelper: "(Ness\<^sup>m\<^sup>a\<^sup>x\<^sub>G \<phi>) \<tau> \<longrightarrow> x \<in> G \<longrightarrow> (\<exists>H. (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub>H \<phi> \<tau>) \<and> x \<in> H)"
proof -
  {fix "G" "\<phi>" "\<tau>" "x"
    {assume 1: "(Ness\<^sup>m\<^sup>a\<^sup>x\<^sub> G \<phi>) \<tau>" and 2: "x \<in> G"
      hence "G = {x. (\<exists>H. ((Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> G \<phi> \<tau>) \<and> x \<in> H))}" by simp
      hence "(\<exists>H. ((Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> G \<phi> \<tau>) \<and> x \<in> H))" using 2 by blast}
    hence "(Ness\<^sup>m\<^sup>a\<^sup>x\<^sub> G \<phi>) \<tau> \<longrightarrow> x \<in> G \<longrightarrow> (\<exists>H. (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> H \<phi> \<tau>) \<and> x \<in> H)" by blast}
  thus ?thesis by auto
qed

lemma Nesses: "(Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> G \<phi>) = (Ness\<^sub> G \<phi>) \<^bold>\<and> (\<^bold>\<not> \<^bold>\<Or> {x.\<exists>H. H \<subset> G \<and> x = (Ness\<^sub> H \<phi>)})"
proof -
  {fix "G" "\<phi>"
  {fix "\<tau>"
  {assume "\<tau> \<^bold>\<Turnstile> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> G \<phi>)"
    hence "\<tau> \<^bold>\<Turnstile> ((Ness\<^sub> G \<phi>) \<^bold>\<and> (\<^bold>\<not> \<^bold>\<Or> {x.\<exists>H.  H \<subset> G \<and> x = (Ness\<^sub> H \<phi>)}))" using mem_Collect_eq by blast}
  hence l: "\<tau> \<^bold>\<Turnstile> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> G \<phi>) \<longrightarrow> \<tau> \<^bold>\<Turnstile> ((Ness\<^sub> G \<phi>) \<^bold>\<and> (\<^bold>\<not> \<^bold>\<Or> {x.\<exists>H.  H \<subset> G \<and> x = (Ness\<^sub> H \<phi>)}))" by blast
  {assume asm2: "\<tau> \<^bold>\<Turnstile> ((Ness\<^sub> G \<phi>) \<^bold>\<and> (\<^bold>\<not> \<^bold>\<Or> {x.\<exists>H.  H \<subset> G \<and> x = (Ness\<^sub> H \<phi>)}))"
    {assume "((\<exists> H. (H \<subset> G) \<and> (Ness\<^sub> H \<phi> \<tau>)))"
    then obtain K where " (K \<subset> G) \<and> (Ness\<^sub> K \<phi> \<tau>)" by auto
    hence "\<tau> \<^bold>\<Turnstile> \<^bold>\<Or> {x.\<exists>H.  H \<subset> G \<and> x = (Ness\<^sub> H \<phi>)}" by auto
    hence False using asm2 by simp}
  hence "\<tau> \<^bold>\<Turnstile> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> G \<phi>)" using asm2 by argo}
  hence "\<tau> \<^bold>\<Turnstile> ((Ness\<^sub> G \<phi>) \<^bold>\<and> (\<^bold>\<not> \<^bold>\<Or> {x.\<exists>H.  H \<subset> G \<and> x = (Ness\<^sub> H \<phi>)})) \<longrightarrow> \<tau> \<^bold>\<Turnstile> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> G \<phi>)" by blast
  hence "\<tau> \<^bold>\<Turnstile> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> G \<phi>) \<longleftrightarrow> \<tau> \<^bold>\<Turnstile> ((Ness\<^sub> G \<phi>) \<^bold>\<and> (\<^bold>\<not> \<^bold>\<Or> {x.\<exists>H. H \<subset> G \<and> x = (Ness\<^sub> H \<phi>)}))" using l by argo}
  hence "(Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> G \<phi>) = (Ness\<^sub> G \<phi>) \<^bold>\<and> (\<^bold>\<not> \<^bold>\<Or> {x.\<exists>H. H \<subset> G \<and> x = (Ness\<^sub> H \<phi>)})" by simp}
  thus ?thesis by simp
qed

abbreviation dumbFunction :: "\<mu> set \<Rightarrow> (\<mu> set \<Rightarrow> bool) \<Rightarrow> nat"
  where "dumbFunction G Rel \<equiv> Min {n. \<exists>H. H \<subseteq> G \<and> n = card H \<and> Rel H}"

lemma RelFinite: "(Rel::\<mu> set \<Rightarrow> bool) G \<longrightarrow> finite {n. \<exists>H. H \<subseteq> G \<and> n = card H \<and> Rel H}"
proof -
{fix Rel G
    {assume "(Rel::\<mu> set \<Rightarrow> bool) G"
      let ?m = "card Ag"
      have "\<forall>a. a \<in> {n. \<exists>H. H \<subseteq> G \<and> n = card H \<and> Rel H} \<longrightarrow> a \<le> ?m" using card_mono finiteActors by blast
      hence a: "finite {n. \<exists>H. H \<subseteq> G \<and> n = card H \<and> Rel H}" by (meson finite_nat_set_iff_bounded_le)}
    hence "(Rel::\<mu> set \<Rightarrow> bool) G \<longrightarrow> finite  {n. \<exists>H. H \<subseteq> G \<and> n = card H \<and> Rel H}" by blast}
  thus ?thesis by simp
qed

lemma "Rel G \<longrightarrow> dumbFunction G Rel \<le> card G"
proof -
  {fix Rel G
    {assume "(Rel::\<mu> set \<Rightarrow> bool) G"
      let ?m = "card Ag"
      have a: "finite {n. \<exists>H. H \<subseteq> G \<and> n = card H \<and> Rel H}" using RelFinite \<open>Rel G\<close> by presburger
      have "G \<subseteq> G \<and> card G = card G \<and> Rel G" using \<open>Rel G\<close> by blast
      hence "card G \<in> {n. \<exists>H. H \<subseteq> G \<and> n = card H \<and> Rel H}" by auto
      hence "{} \<noteq> {n. \<exists>H. H \<subseteq> G \<and> n = card H \<and> Rel H}" by blast
      hence "dumbFunction G Rel \<le> ?m" using a by (metis (no_types, lifting) Min_le_iff \<open>card G \<in> {n. \<exists>H\<subseteq>G. n = card H \<and> Rel H}\<close> card_mono finiteActors top_greatest)
      hence "card G \<ge> dumbFunction G Rel" using Min_le \<open>Rel G\<close> a by blast}
    hence "Rel G \<longrightarrow> dumbFunction G Rel \<le> card G" by simp}
  thus ?thesis by simp
qed

lemma minimalexists: "(Rel::\<mu> set \<Rightarrow> bool) G \<longrightarrow> (\<exists>H\<subseteq>G. Rel H \<and> (\<not> (\<exists>K \<subset> H. (Rel K))))"
proof -
  {fix Rel G
    {assume "(Rel::\<mu> set \<Rightarrow> bool) G"
      hence "\<exists>n. (n = dumbFunction G Rel)" by simp
      then obtain n where obtn: "n = dumbFunction G Rel" by auto
      have "finite {n. \<exists>H. H \<subseteq> G \<and> n = card H \<and> Rel H}" using RelFinite \<open>Rel G\<close> by presburger
      hence "\<exists>H. H \<subseteq> G \<and> n = card H \<and> Rel H" using Min_in obtn \<open>Rel G\<close> by auto
      then obtain H where obtH: "H \<subseteq> G \<and> n = card H \<and> Rel H" by auto
      {assume red: "\<exists>K \<subset> H. (Rel K)"
        then obtain K where obtK: "K \<subset> H \<and> (Rel K)" by auto
        hence "K \<subseteq> G \<and> Rel K" using obtH by blast
        hence c: "card K \<in> {n. \<exists>H. H \<subseteq> G \<and> n = card H \<and> Rel H}" by auto
        have "card K < n" using obtK by (metis finiteActors finite_subset obtH psubset_card_mono top_greatest)
        hence False using Min_le \<open>finite {n. \<exists>H\<subseteq>G. n = card H \<and> Rel H}\<close> c not_less obtn by blast}
      hence "\<not> (\<exists>K \<subset> H. (Rel K))" by blast
      hence "(\<exists>H\<subseteq>G. Rel H \<and> (\<not> (\<exists>K \<subset> H. (Rel K))))" using obtH by auto}
    hence "(Rel::\<mu> set \<Rightarrow> bool) G \<longrightarrow> (\<exists>H\<subseteq>G. Rel H \<and> (\<not> (\<exists>K \<subset> H. (Rel K))))" by simp}
  thus ?thesis by simp
qed

lemma Proposition1: "(\<tau> \<^bold>\<Turnstile> (Ness\<^sub> G \<phi>) \<longleftrightarrow> (\<tau> \<^bold>\<Turnstile> (\<^bold>[Ag\<^bold>]\<phi>)) \<and> \<not>(\<tau> \<^bold>\<Turnstile> (\<^bold>[Ag - G\<^bold>]\<phi>)))" by blast

lemma "(G \<subseteq> H) \<longrightarrow> \<lfloor>(\<^bold>\<not>(\<^bold>[Ag -H\<^bold>]\<phi>)) \<^bold>\<rightarrow> (\<^bold>\<not>(\<^bold>[Ag-H\<^bold>]\<phi>))\<rfloor>" by auto

lemma Proposition2a: "(Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi> \<tau>) \<longrightarrow> x \<in> (Core \<phi> \<tau>)"
proof-
  {fix x \<phi> \<tau>
    assume asm: "(Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x::\<mu>} \<phi> (\<tau>::i))"
      {assume red: "x \<notin> (Core \<phi> \<tau>)"
        from asm have "(Ness\<^sub> {x} \<phi> \<tau>) \<and> ((\<forall>H \<subset> {x}. \<not> (Ness\<^sub> H \<phi> \<tau>)))" by blast
        hence "(Ness\<^sub> {x} \<phi> \<tau>) \<and> \<not> (Ness\<^sub> {} \<phi> \<tau>)" by blast
        hence a: "(Ness\<^sub> {x} \<phi> \<tau>)" by simp
        from Proposition1 have p1: "(\<tau> \<^bold>\<Turnstile> (Ness\<^sub> {x} \<phi>) \<longleftrightarrow> (\<tau> \<^bold>\<Turnstile> (\<^bold>[Ag\<^bold>]\<phi>)) \<and> \<not>(\<tau> \<^bold>\<Turnstile> (\<^bold>[Ag - {x}\<^bold>]\<phi>)))" by presburger
        hence "\<not> (\<^bold>[Ag -{x}\<^bold>]\<phi>) \<tau>" using a by simp
        have ag: "(\<^bold>[Ag\<^bold>]\<phi>) \<tau>" using p1 a by simp
        let ?Rel = "\<lambda>K. (\<^bold>[K\<^bold>]\<phi>) \<tau>"
        from minimalexists have "\<forall> Rel G.(Rel::\<mu> set \<Rightarrow> bool) G \<longrightarrow> (\<exists>H\<subseteq>G. Rel H \<and> (\<not> (\<exists>K \<subset> H. (Rel K))))" by simp
        hence "\<forall> Rel.(Rel::\<mu> set \<Rightarrow> bool) Ag \<longrightarrow> (\<exists>H\<subseteq>Ag. Rel H \<and> (\<not> (\<exists>K \<subset> H. (Rel K))))" by blast
        hence "(?Rel::\<mu> set \<Rightarrow> bool) Ag \<longrightarrow> (\<exists>H\<subseteq>Ag. ?Rel H \<and> (\<not> (\<exists>K \<subset> H. (?Rel K))))" by (rule allE)
        hence "(\<exists>H\<subseteq>Ag. ?Rel H \<and> (\<not> (\<exists>K \<subset> H. (?Rel K))))" using ag by simp
        then obtain H where obtH: "H \<subseteq> Ag \<and> ((\<^bold>[H\<^bold>]\<phi>) \<tau>) \<and> (\<not> (\<exists>K \<subset> H. ((\<^bold>[K\<^bold>]\<phi>) \<tau>)))" by auto
        hence ex: "\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> H \<phi>)" by simp
        hence ex2: "x \<in> H" by (metis DiffI UNIV_I \<open>\<not> \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> (Ag - {x}) \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>\<close> singletonD)
        from red have "x \<notin> \<^bold>\<inter> {H. ((\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> H \<phi>)(\<tau>::i))}" by simp
        hence  "x \<notin> {x. (\<exists>M \<in> {H. ((\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> H \<phi>)(\<tau>::i))}. (x \<in> M)) \<and> (\<forall> M \<in> {H. ((\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> H \<phi>)(\<tau>::i))}. x \<in> M)}" by simp
        hence "\<exists>K. (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> K \<phi>)(\<tau>::i) \<and> x \<notin> K" using ex ex2 by blast
        then obtain K where obtK: "(\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> K \<phi>)(\<tau>::i) \<and> x \<notin> K" by auto
          hence "(\<^bold>[Ag -{x}\<^bold>]\<phi>) \<tau>" by auto
          hence False using \<open>((\<exists>K. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> K \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>) \<and> (\<forall>H. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> H \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor> \<longrightarrow> \<not> \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> (H - {x}) \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>)) \<and> (\<forall>H\<subset>{x}. \<not> ((\<exists>K. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> K \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>) \<and> (\<forall>Ha. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> Ha \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor> \<longrightarrow> \<not> \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> (Ha - H) \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>)))\<close> p1 by blast}
        hence "x \<in> Core \<phi> \<tau>" by blast}
      thus ?thesis by presburger
qed

lemma Proposition2b: "(x \<in> (Core \<phi> \<tau>)) \<longrightarrow> (\<tau> \<^bold>\<Turnstile> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi>))"
proof -
    {assume "x \<in> (Core \<phi> \<tau>)"
      {assume "\<not> (\<tau> \<^bold>\<Turnstile> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi>))"
        hence a: "(\<not> Ness\<^sub> {x} \<phi> \<tau>) \<or> ((\<exists> H. (H \<subset> {x}) \<and> (Ness\<^sub> H \<phi> \<tau>)))" by blast
        have "(\<exists> H. (H \<subset> {x}) \<and> (Ness\<^sub> H \<phi> \<tau>)) \<longleftrightarrow> (Ness\<^sub> {} \<phi> \<tau>)" by fast
        hence "(\<not> (Ness\<^sub> {x} \<phi> \<tau>)) \<or> (Ness\<^sub> {} \<phi> \<tau>)" using a by auto
        {assume "(Ness\<^sub> {} \<phi> \<tau>)"
          hence False by auto}
        {assume "(\<not> (Ness\<^sub> {x} \<phi> \<tau>))"
          hence "(\<not> (\<exists>(K::\<mu> set). (\<tau> \<^bold>\<Turnstile> (\<^bold>[K\<^bold>]\<phi>)))) \<or> (\<exists>H. (\<tau> \<^bold>\<Turnstile> (\<^bold>[H\<^bold>]\<phi>)) \<and> (\<tau> \<^bold>\<Turnstile> (\<^bold>[H - {x}\<^bold>]\<phi>)))" by blast
          {assume "\<not> (\<exists>(K::\<mu> set). (\<tau> \<^bold>\<Turnstile> (\<^bold>[K\<^bold>]\<phi>)))"
            hence False using \<open>x \<in> \<^bold>\<inter> {H. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> H \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor> \<and> \<not> (\<exists>Ha\<subset>H. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> Ha \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>)}\<close> by auto}
          {assume "\<exists>H. (\<tau> \<^bold>\<Turnstile> (\<^bold>[H\<^bold>]\<phi>)) \<and> (\<tau> \<^bold>\<Turnstile> (\<^bold>[H - {x}\<^bold>]\<phi>))"
            then obtain H where obtH: "(\<tau> \<^bold>\<Turnstile> (\<^bold>[H\<^bold>]\<phi>)) \<and> (\<tau> \<^bold>\<Turnstile> (\<^bold>[H - {x}\<^bold>]\<phi>))" by auto
            let ?Rel = "\<lambda>K. (\<^bold>[K\<^bold>]\<phi>) \<tau>"
            from minimalexists have "\<forall> Rel G.(Rel::\<mu> set \<Rightarrow> bool) G \<longrightarrow> (\<exists>L\<subseteq>G. Rel L \<and> (\<not> (\<exists>K \<subset> L. (Rel K))))" by simp
            hence "\<forall> Rel.(Rel::\<mu> set \<Rightarrow> bool) (H - {x}) \<longrightarrow> (\<exists>L\<subseteq>(H - {x}). Rel L \<and> (\<not> (\<exists>K \<subset> L. (Rel K))))" by simp
            hence "(?Rel::\<mu> set \<Rightarrow> bool) (H - {x}) \<longrightarrow> (\<exists>L\<subseteq>(H - {x}). ?Rel L \<and> (\<not> (\<exists>K \<subset> L. (?Rel K))))" by (rule allE)
            hence " (\<exists>L\<subseteq>(H - {x}). ?Rel L \<and> (\<not> (\<exists>K \<subset> L. (?Rel K))))" using obtH by fastforce
            hence "\<exists>K. (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> K \<phi>)(\<tau>::i) \<and> x \<notin> K" by (metis subset_Diff_insert)
            hence "x \<notin> Core \<phi> \<tau>" by simp
            hence False using \<open>x \<in> \<^bold>\<inter> {H. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> H \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor> \<and> \<not> (\<exists>Ha\<subset>H. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> Ha \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>)}\<close> by blast}
          hence False using \<open>\<nexists>K. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> K \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor> \<Longrightarrow> False\<close> \<open>\<not> ((\<exists>K. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> K \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>) \<and> (\<forall>H. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> H \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor> \<longrightarrow> \<not> \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> (H - {x}) \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>))\<close> by blast}
        hence False using \<open>(\<exists>K. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> K \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>) \<and> (\<forall>H. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> H \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor> \<longrightarrow> \<not> \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> (H - {}) \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>) \<Longrightarrow> False\<close> \<open>\<not> ((\<exists>K. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> K \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>) \<and> (\<forall>H. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> H \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor> \<longrightarrow> \<not> \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> (H - {x}) \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>)) \<or> (\<exists>K. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> K \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>) \<and> (\<forall>H. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> H \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor> \<longrightarrow> \<not> \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> (H - {}) \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>)\<close> by fastforce}
      hence "(\<tau> \<^bold>\<Turnstile> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x::\<mu>} \<phi>))" by blast}
    thus "(x \<in> (Core \<phi> \<tau>)) \<longrightarrow> (\<tau> \<^bold>\<Turnstile> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x::\<mu>} \<phi>))" by blast
  qed

lemma Proposition2: "(Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi> \<tau>) \<longleftrightarrow> x \<in> (Core \<phi> \<tau>)"
proof -
  {assume "\<not> ((Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x::\<mu>} \<phi> (\<tau>::i)) \<longleftrightarrow> x \<in> (Core \<phi> \<tau>))"
    hence or: " (\<not> ((Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x::\<mu>} \<phi> (\<tau>::i)) \<longrightarrow> x \<in> (Core \<phi> \<tau>))) \<or> \<not> ((x \<in> (Core \<phi> \<tau>)) \<longrightarrow> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x::\<mu>} \<phi> (\<tau>::i)))" by blast
    from Proposition2b have "((x \<in> (Core \<phi> \<tau>)) \<longrightarrow> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi> \<tau>))" by -
    hence or2: "(\<not> ((Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x::\<mu>} \<phi> (\<tau>::i)) \<longrightarrow> x \<in> (Core \<phi> \<tau>)))" using or by blast
    from Proposition2a have "((Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x::\<mu>} \<phi> (\<tau>::i)) \<longrightarrow> x \<in> (Core \<phi> \<tau>))" by -
    hence False using or2 by blast}
  thus ?thesis by argo
qed

lemma minDeltaExists: "(\<tau> \<^bold>\<Turnstile> (\<^bold>[G\<^bold>]\<phi>)) \<longrightarrow> (\<exists>H \<subseteq> G. (\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> H \<phi>)))"
proof -
  let ?Rel = "\<lambda>K. (\<^bold>[K\<^bold>]\<phi>) \<tau>"
  from minimalexists have"\<forall>Rel. (Rel::\<mu> set \<Rightarrow> bool) G \<longrightarrow> (\<exists>H\<subseteq>G. Rel H \<and> (\<not> (\<exists>K \<subset> H. (Rel K))))" by simp
  hence "(?Rel::\<mu> set \<Rightarrow> bool) G \<longrightarrow> (\<exists>H\<subseteq>G. ?Rel H \<and> (\<not> (\<exists>K \<subset> H. (?Rel K))))" by (rule allE)
  thus "(\<tau> \<^bold>\<Turnstile> (\<^bold>[G\<^bold>]\<phi>)) \<longrightarrow> (\<exists>H\<subseteq>G. (\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> H \<phi>)))" by auto
qed

lemma Corollary1a: "(G \<noteq> {}) \<longrightarrow> (((\<tau> \<^bold>\<Turnstile> (\<^bold>[G\<^bold>]\<phi>)) \<and> (G = Core \<phi> \<tau>)) \<longrightarrow> \<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>s\<^sup>o\<^sup>l\<^sup>e\<^sub> G \<phi>))"
proof -
  {assume asm1: "G \<noteq> {}"
    and asm2: "\<tau> \<^bold>\<Turnstile> (\<^bold>[G\<^bold>]\<phi>)"
    and asm3: "G = Core \<phi> \<tau>"
    {assume red:"(\<exists> H. (H \<subset> G) \<and> ((\<^bold>[H\<^bold>]\<phi>) \<tau>))"
      then obtain H where obtH: "(H \<subset> G) \<and> ((\<^bold>[H\<^bold>]\<phi>) \<tau>)" by auto
      {assume "H = {}"
        hence "Core \<phi> \<tau> = {}" using obtH by auto
        hence False using asm3 obtH asm1 by fastforce}
      hence ne: "H \<noteq> {}" by blast
      hence "\<exists>x\<in>G. x \<notin> H" using obtH by blast
      then obtain x where obtx: "x \<in> G \<and> x \<notin> H" by auto
      have "Core \<phi> \<tau> \<noteq> {}" using asm1 asm3 by simp
      hence fa: "\<forall>y. ((y \<in> Core \<phi> \<tau>) \<longrightarrow> (\<forall>K. (\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> K \<phi>)) \<longrightarrow> y \<in> K))" by simp
      from minDeltaExists obtH have "\<exists>K\<subseteq>H. (\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> K \<phi>))" by simp
      then obtain K where obtK: "K\<subseteq>H \<and> (\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> K \<phi>))" by auto
      hence "x \<notin> K" using obtx by auto
      hence "\<exists>K. (\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> K \<phi>)) \<and> x \<notin> K" using obtK by auto
      hence "x \<notin> Core \<phi> \<tau>" using fa by force
      hence False using obtx asm3 by blast}
    hence "\<not> (\<exists> H. (H \<subset> G) \<and> ((\<^bold>[H\<^bold>]\<phi>) \<tau>))" by blast
    hence one: "\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> G \<phi>)" using asm2 by simp
    {assume red2: "\<not> (\<^bold>\<Delta>\<^sup>m\<^sup>a\<^sup>x\<^sub> G \<phi>) \<tau>"
      from one have "\<exists>M. (\<^bold>\<Delta>\<^sup>m\<^sup>a\<^sup>x\<^sub> M \<phi>) \<tau>" by presburger
      then obtain M where obtmax: "(\<^bold>\<Delta>\<^sup>m\<^sup>a\<^sup>x\<^sub> M \<phi>) \<tau>" by auto
      {assume "G \<noteq> M"
        hence a: "M \<supset> G " using obtmax Collect_mono_iff asm3 mem_Collect_eq psubsetI by auto
        hence "\<exists>x\<in>M. x\<notin>G" by auto
        then obtain x where obtx: "x \<in> M \<and> x \<notin> G" by auto
        hence "x \<in> {x. (\<exists>K. (((\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> K \<phi>) \<tau>) \<and> x \<in> K))}" using obtmax by simp
        hence "\<exists>H. ((\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> H \<phi>) \<tau>) \<and> x \<in> H" by simp
        then obtain H where obtH: "(\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> H \<phi>) \<tau> \<and> x \<in> H" by auto
        {assume "\<exists>y \<in> G. y \<notin> H"
          then obtain y where obty: "y \<in> G \<and> y \<notin> H" by auto
          hence "y \<notin> Core \<phi> \<tau>" using obtH by auto
          hence False using asm3 obty by argo}
        hence "H \<supseteq> G" by auto
        hence "H \<supset> G" using obtx obtH by auto
        hence False using obtH asm2 by blast}
      hence "G = M" by blast
      hence "(\<^bold>\<Delta>\<^sup>m\<^sup>a\<^sup>x\<^sub> G \<phi>) \<tau>" using obtmax by auto
      hence False using red2 by blast}
    hence "(\<^bold>\<Delta>\<^sup>m\<^sup>a\<^sup>x\<^sub> G \<phi>) \<tau>" by blast
    hence "\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>s\<^sup>o\<^sup>l\<^sup>e\<^sub> G \<phi>)" using one by blast}
  thus ?thesis by argo
qed

lemma Corollary1b: "(G \<noteq> {}) \<longrightarrow> (\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>s\<^sup>o\<^sup>l\<^sup>e\<^sub> G \<phi>) \<longrightarrow> ((\<tau> \<^bold>\<Turnstile> (\<^bold>[G\<^bold>]\<phi>)) \<and> (G = Core \<phi> \<tau>)))"
proof -
    {assume asm: "G \<noteq> {}" and asm2: "\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>s\<^sup>o\<^sup>l\<^sup>e\<^sub> G \<phi>)"
      hence 1: "\<tau> \<^bold>\<Turnstile> (\<^bold>[G\<^bold>]\<phi>)" by blast
      have 2: "\<not>(\<exists> H. (H \<subset> G) \<and> (\<^bold>[H\<^bold>]\<phi>) \<tau>)" using asm2 by argo
      have "Core \<phi> \<tau> \<subseteq> G" using asm2 by blast
      have "G \<subseteq> Core \<phi> \<tau>"
      proof -
      {assume red: "\<exists>x. x \<in> G \<and> x \<notin> Core \<phi> \<tau>"
        then obtain x where obtx: "x \<in> G \<and> x \<notin> Core \<phi> \<tau>" by presburger
        hence nm: "\<not> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi> \<tau>)" using Proposition2 by simp
        have "\<not> \<tau> \<^bold>\<Turnstile> (\<^bold>[{}\<^bold>]\<phi>)" using 1 2 asm by blast
        hence "\<not>(\<exists> H. (H \<subset> {x}) \<and> (Ness\<^sub> H \<phi> \<tau>))" by (metis Diff_empty Diff_insert_absorb bot.extremum_strict less_imp_le psubset_insert_iff singleton_insert_inj_eq)
        hence nn: "\<not> Ness\<^sub> {x} \<phi> \<tau>" using nm by blast
        from 1 have "\<tau> \<^bold>\<Turnstile> (\<^bold>[Ag\<^bold>]\<phi>)" by simp
        hence "\<tau> \<^bold>\<Turnstile> (\<^bold>[Ag - {x}\<^bold>]\<phi>)" using Proposition1 nn by blast
        have ff: "\<forall>H. \<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> H \<phi>) \<longrightarrow> x \<in> H"
        proof -
          {fix H
            assume asmH: "\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> H \<phi>)"
              hence "H \<subseteq> G" using asm2 by blast
              hence "H = G" using asmH \<open>H \<subseteq> G\<close> using asm2 by (meson order.not_eq_order_implies_strict)
              hence "x \<in> H" by (simp add: obtx)}
            thus "\<forall>H. \<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> H \<phi>) \<longrightarrow> x \<in> H" by simp
          qed
          have "\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> (G::\<mu> set) \<phi>)" using 1 2 by simp
          hence "x \<in> Core \<phi> \<tau>" using ff by auto
          hence False using obtx by fastforce}
        thus ?thesis by blast
      qed
      hence "G = Core \<phi> \<tau>" using \<open>\<^bold>\<inter> {H. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> H \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor> \<and> \<not> (\<exists>Ha\<subset>H. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> Ha \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>)} \<subseteq> G\<close> by blast}
    thus "(G \<noteq> {}) \<longrightarrow> (\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>s\<^sup>o\<^sup>l\<^sup>e\<^sub> G \<phi>) \<longrightarrow> ((\<tau> \<^bold>\<Turnstile> (\<^bold>[G\<^bold>]\<phi>)) \<and> (G = Core \<phi> \<tau>)))" by argo
qed

lemma Corollary1: "G \<noteq> {} \<longrightarrow>(((\<tau> \<^bold>\<Turnstile> (\<^bold>[G\<^bold>]\<phi>)) \<and> (G = Core \<phi> \<tau>)) \<longleftrightarrow> \<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>s\<^sup>o\<^sup>l\<^sup>e\<^sub> G \<phi>))"
proof -
  {assume asm: "G \<noteq> {}"
    have "G \<noteq> {} \<longrightarrow> (((\<tau> \<^bold>\<Turnstile> (\<^bold>[G\<^bold>]\<phi>)) \<and> (G = Core \<phi> \<tau>)) \<longrightarrow> \<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>s\<^sup>o\<^sup>l\<^sup>e\<^sub> G \<phi>))" using Corollary1a by -
    hence lr: "(((\<tau> \<^bold>\<Turnstile> (\<^bold>[G\<^bold>]\<phi>)) \<and> (G = Core \<phi> \<tau>)) \<longrightarrow> \<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>s\<^sup>o\<^sup>l\<^sup>e\<^sub> G \<phi>))" using asm by (rule mp)
    have "(G \<noteq> {}) \<longrightarrow> (\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>s\<^sup>o\<^sup>l\<^sup>e\<^sub> G \<phi>) \<longrightarrow> ((\<tau> \<^bold>\<Turnstile> (\<^bold>[G\<^bold>]\<phi>)) \<and> (G = Core \<phi> \<tau>)))" using Corollary1b by -
    hence "(\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>s\<^sup>o\<^sup>l\<^sup>e\<^sub> G \<phi>) \<longrightarrow> ((\<tau> \<^bold>\<Turnstile> (\<^bold>[G\<^bold>]\<phi>)) \<and> (G = Core \<phi> \<tau>)))" using asm by (rule mp)
    hence "(((\<tau> \<^bold>\<Turnstile> (\<^bold>[G\<^bold>]\<phi>)) \<and> (G = Core \<phi> \<tau>)) \<longleftrightarrow> \<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>s\<^sup>o\<^sup>l\<^sup>e\<^sub> G \<phi>))" using lr by argo}
  thus ?thesis by blast (*this whole proof is pointless, but my hardware cant prove it on its own*)
qed

lemma Proposition3: "G \<noteq> {} \<longrightarrow>((\<tau> \<^bold>\<Turnstile> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> G \<phi>)) \<longleftrightarrow> (G \<subseteq> H) \<and> (\<tau> \<^bold>\<Turnstile>((\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub>H \<phi>) \<^bold>\<and> \<^bold>\<not>\<^bold>[H - G\<^bold>]\<phi>)) \<and> (\<not> (\<exists>K. K \<subset> H \<and> (\<tau> \<^bold>\<Turnstile>((\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub>K \<phi>) \<^bold>\<and> \<^bold>\<not>\<^bold>[K - G\<^bold>]\<phi>)))))"
  oops
(*Nitpick finds a counterexample here too*)

lemma Proposition3a: "G \<noteq> {} \<longrightarrow>((\<tau> \<^bold>\<Turnstile> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub>G \<phi>)) \<longrightarrow> (G \<subseteq> H) \<and> (\<tau> \<^bold>\<Turnstile>((\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub>H \<phi>) \<^bold>\<and> \<^bold>\<not>\<^bold>[H - G\<^bold>]\<phi>)) \<and> (\<not> (\<exists>K. K \<subset> H \<and> (\<tau> \<^bold>\<Turnstile>((\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub>K \<phi>) \<^bold>\<and> \<^bold>\<not>\<^bold>[K - G\<^bold>]\<phi>)))))" nitpick[user_axioms]
  oops
(*Nitpick finds a counterexample here too*)
lemma Proposition3b: "G \<noteq> {} \<longrightarrow> ((G \<subseteq> H) \<and> (\<tau> \<^bold>\<Turnstile>((\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub>H \<phi>) \<^bold>\<and> \<^bold>\<not>\<^bold>[H - G\<^bold>]\<phi>)) \<and> (\<not> (\<exists>K. K \<subset> H \<and> (\<tau> \<^bold>\<Turnstile>((\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> K \<phi>) \<^bold>\<and> \<^bold>\<not>\<^bold>[K - G\<^bold>]\<phi>)))) \<longrightarrow> ((\<tau> \<^bold>\<Turnstile> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> G \<phi>))))" nitpick[user_axioms]
  oops
(*Nitpick finds a counterexample here too*)

lemma Proposition5: "G \<noteq> {} \<longrightarrow> \<lfloor>(\<^bold>[Ag\<^bold>]\<phi>) \<^bold>\<rightarrow> ((Could\<^sub> G (\<^bold>\<not>\<phi>)) \<^bold>\<rightarrow> (Ness\<^sub> G \<phi>))\<rfloor>" by (meson DiffD2 DiffI iso_tuple_UNIV_I tildexeq xsub)

lemma eqcompr: "(\<forall>\<tau>. \<tau> \<^bold>\<Turnstile> \<phi> \<longleftrightarrow> \<tau> \<^bold>\<Turnstile> \<psi>) \<longleftrightarrow> \<phi> = \<psi>"
proof-
  have rl: "\<phi> = \<psi> \<longrightarrow> (\<forall>\<tau>. \<tau> \<^bold>\<Turnstile> \<phi> \<longleftrightarrow> \<tau> \<^bold>\<Turnstile> \<psi>)" by simp
  have "(\<forall>\<tau>. \<tau> \<^bold>\<Turnstile> \<phi> \<longleftrightarrow> \<tau> \<^bold>\<Turnstile> \<psi>) \<longrightarrow> \<phi> = \<psi>" by auto
  thus ?thesis using rl by blast
qed

lemma NessEq: "Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi> = Ness\<^sub> {x} \<phi>"
proof -
  {fix \<tau>
    {assume "\<tau> \<^bold>\<Turnstile> Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi>"
      hence "\<tau> \<^bold>\<Turnstile>Ness\<^sub> {x} \<phi>" by simp}
    {assume "\<tau> \<^bold>\<Turnstile>Ness\<^sub> {x} \<phi>"
      hence "\<not> \<tau> \<^bold>\<Turnstile>(\<^bold>[{}\<^bold>]\<phi>)" by (meson equals0D)
      hence " \<not>(\<exists> H. (H \<subset> {x}) \<and> (Ness\<^sub> H \<phi> \<tau>))" by (metis Diff_empty Diff_insert_absorb bot.extremum_strict less_imp_le psubset_insert_iff singleton_insert_inj_eq)
      hence "\<tau> \<^bold>\<Turnstile> Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi>" using \<open>(\<exists>K. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> K \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>) \<and> (\<forall>H. \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> H \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor> \<longrightarrow> \<not> \<lfloor>(\<lambda>v. v \<^bold>\<Turnstile> tildeG \<tau> (H - {x}) \<longrightarrow> v \<^bold>\<Turnstile> \<phi>)\<rfloor>)\<close> by blast}
    hence "\<tau> \<^bold>\<Turnstile> Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi> \<longleftrightarrow> \<tau> \<^bold>\<Turnstile> Ness\<^sub> {x} \<phi>" by blast}
  hence a: "\<forall>\<tau>. (\<tau> \<^bold>\<Turnstile> Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi> \<longleftrightarrow> \<tau> \<^bold>\<Turnstile> Ness\<^sub> {x} \<phi>)" by simp
  from eqcompr have "\<forall>z y. ((\<forall>\<tau>. \<tau> \<^bold>\<Turnstile> z \<longleftrightarrow> \<tau> \<^bold>\<Turnstile> y) \<longleftrightarrow> z = y)" by simp
  hence "\<forall>y. ((\<forall>\<tau>. \<tau> \<^bold>\<Turnstile> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi>) \<longleftrightarrow> \<tau> \<^bold>\<Turnstile> y) \<longleftrightarrow> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi>) = y)" by (rule allE)
  hence "((\<forall>\<tau>. \<tau> \<^bold>\<Turnstile> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi>) \<longleftrightarrow> \<tau> \<^bold>\<Turnstile> (Ness\<^sub> {x} \<phi>)) \<longleftrightarrow> (Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi>) = (Ness\<^sub> {x} \<phi>))" by (rule allE)
  hence"(Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi>) = (Ness\<^sub> {x} \<phi>)" using a by simp
  thus ?thesis by simp
qed

lemma Corollary2: "\<lfloor>(\<^bold>[Ag\<^bold>]\<phi>) \<^bold>\<rightarrow> ((Could\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} (\<^bold>\<not>\<phi>)) \<^bold>\<rightarrow> Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi>)\<rfloor>"
proof -
  from Proposition5 have "\<forall>G. G \<noteq> {} \<longrightarrow> \<lfloor>(\<^bold>[Ag\<^bold>]\<phi>) \<^bold>\<rightarrow> ((Could\<^sub> G (\<^bold>\<not>\<phi>)) \<^bold>\<rightarrow> (Ness\<^sub> G \<phi>))\<rfloor>" by simp
  hence a: "\<forall>G. G \<noteq> {} \<longrightarrow> \<lfloor>(\<^bold>[Ag\<^bold>]\<phi>) \<^bold>\<rightarrow> ((Could\<^sup>m\<^sup>i\<^sup>n\<^sub> G (\<^bold>\<not>\<phi>)) \<^bold>\<rightarrow> (Ness\<^sub> G \<phi>))\<rfloor>" by simp
  have "{x} \<noteq> {}" by simp
  hence b: "\<lfloor>(\<^bold>[Ag\<^bold>]\<phi>) \<^bold>\<rightarrow> ((Could\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} (\<^bold>\<not>\<phi>)) \<^bold>\<rightarrow> (Ness\<^sub> {x} \<phi>))\<rfloor>" using a by presburger
  from NessEq have eq: "(Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi>) = (Ness\<^sub> {x} \<phi>)" by -
  let ?d = "(Ness\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} \<phi>)"
  let ?c = "(Ness\<^sub> {x} \<phi>)"
  have "\<forall>c d a b. \<lfloor>a \<^bold>\<rightarrow> (b \<^bold>\<rightarrow> c)\<rfloor> \<longrightarrow> d = c \<longrightarrow> \<lfloor>a \<^bold>\<rightarrow> (b \<^bold>\<rightarrow> d)\<rfloor>" by simp
  hence "\<forall> d a b. \<lfloor>a \<^bold>\<rightarrow> (b \<^bold>\<rightarrow> ?c)\<rfloor> \<longrightarrow> d = ?c \<longrightarrow> \<lfloor>a \<^bold>\<rightarrow> (b \<^bold>\<rightarrow> d)\<rfloor>" by (rule allE)
  hence "\<forall>a b. \<lfloor>a \<^bold>\<rightarrow> (b \<^bold>\<rightarrow> ?c)\<rfloor> \<longrightarrow> ?d = ?c \<longrightarrow> \<lfloor>a \<^bold>\<rightarrow> (b \<^bold>\<rightarrow> ?d)\<rfloor>" by (rule allE)
  hence "\<forall>a b. \<lfloor>a \<^bold>\<rightarrow> (b \<^bold>\<rightarrow> ?c)\<rfloor> \<longrightarrow> \<lfloor>a \<^bold>\<rightarrow> (b \<^bold>\<rightarrow> ?d)\<rfloor>" using eq by simp
  hence "\<forall>b. \<lfloor>(\<^bold>[Ag\<^bold>]\<phi>) \<^bold>\<rightarrow> (b \<^bold>\<rightarrow> ?c)\<rfloor> \<longrightarrow> \<lfloor>(\<^bold>[Ag\<^bold>]\<phi>) \<^bold>\<rightarrow> (b \<^bold>\<rightarrow> ?d)\<rfloor>" by (rule allE)
  hence "\<lfloor>(\<^bold>[Ag\<^bold>]\<phi>) \<^bold>\<rightarrow> ((Could\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} (\<^bold>\<not>\<phi>)) \<^bold>\<rightarrow> ?c)\<rfloor> \<longrightarrow> \<lfloor>(\<^bold>[Ag\<^bold>]\<phi>) \<^bold>\<rightarrow> ((Could\<^sup>m\<^sup>i\<^sup>n\<^sub> {x} (\<^bold>\<not>\<phi>)) \<^bold>\<rightarrow> ?d)\<rfloor>" by (rule allE)
  thus ?thesis using b by auto
qed

lemma Coresubs: "\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> G \<phi>) \<longrightarrow> (Core \<phi> \<tau>) \<subseteq> G" by auto

lemma emptneq: "a \<noteq> b \<longrightarrow> \<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> {a} \<phi>) \<longrightarrow> \<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> {b} \<phi>) \<longrightarrow> (Core \<phi> \<tau>) = {}"
proof -
  {assume asm1: "a \<noteq> b"
    and asm2: "\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> {a} \<phi>)"
    and asm3: "\<tau> \<^bold>\<Turnstile> (\<^bold>\<Delta>\<^sup>m\<^sup>i\<^sup>n\<^sub> {b} \<phi>)"
    hence "(Core \<phi> \<tau>) \<subseteq> {a} \<and> (Core \<phi> \<tau>) \<subseteq> {b}" using Coresubs asm2 asm3 by simp
    hence "(Core \<phi> \<tau>) = {}" using asm1 by blast}
  thus ?thesis by simp
qed

lemma memin: "(\<tau> ~ (G::\<mu> set) \<tau>b) \<longrightarrow> x \<in> G \<longrightarrow> \<tau>b \<in> (alt\<^sub> x \<tau>)" by blast

lemma inmem: "(\<forall>x \<in> G. \<tau>b \<in> (alt\<^sub> x \<tau>)) \<longrightarrow> (\<tau> ~ (G::\<mu> set) \<tau>b)" using tildeeqU by auto

lemma singletonacc: "(\<tau> ~ {x} \<tau>b) \<longleftrightarrow> ((\<tau>\<^bold>~(x::\<mu>)\<tau>b))"
  using xsub by auto

lemma eqclassalt: "y \<in> alt\<^sub> x (\<tau>) \<longrightarrow> ((y::i)\<^bold>~(x::\<mu>)(z::i)) \<longrightarrow> z \<in> (alt\<^sub> x (\<tau>))"
  by (metis mem_Collect_eq tildexeq)

lemma eqclassalt2: "cla \<in> (\<^bold>A\<^sub> x) \<longrightarrow> y \<in> cla \<longrightarrow> ((y::i)\<^bold>~(x::\<mu>)(z::i)) \<longrightarrow> z \<in> cla"
  using eqclassalt by blast

lemma eqclassalt3: "cla \<in> (\<^bold>A\<^sub> x) \<longrightarrow> y \<in> cla \<longrightarrow> z \<in> cla \<longrightarrow> ((y::i)\<^bold>~(x::\<mu>)(z::i))" using mem_Collect_eq tildexeq
  by (smt (verit, del_insts))

lemma ac: "action \<in> (\<^bold>A\<^sub> x) \<longrightarrow> z \<in> action \<longrightarrow> y \<in> action \<longrightarrow> (z \<^bold>~x y)"
  using eqclassalt3 by blast
lemma rac: "action \<in> (\<^bold>A\<^sub> x) \<longrightarrow> z \<in> action \<longrightarrow> (z \<^bold>~x y) \<longrightarrow> y \<in> action"
  using eqclassalt by blast

end


theory flash46Bra  imports flash46Rev

  begin
lemma onInv46:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


theory tp89
imports Main "~~/src/HOL/Library/Code_Target_Nat"
begin

(*
quickcheck_params [size=6,tester=narrowing,timeout=120]
nitpick_params [timeout=120]
*)

type_synonym transid= "nat*nat*nat" (*c,m,i*)

datatype message=
  Pay transid nat
| Ack transid nat
| Cancel transid

type_synonym transaction= "transid * nat" (* ((c,m,i),am) *)

(*********MY TYPES OF VARS**********)

(*  messageList
  list of messages still to be processed.
*)
type_synonym messageList = "message list"

(*  vals
  contain an amount or None
*)
type_synonym vals= "nat option"

(*  transidvals
  contain the transid, the current amount expected to be paid by the client, and the current amount expected to be sold by the marchant, and if the transaction is still possible or not
transid * pay_amount * sell_amount * is the transaction not closed nor validated
*)
type_synonym transidvals = "transid * vals * vals * bool" (* ((c,m,i),amc,amm,isAvailable) *)

(*  transBdd
  list of transidvals that are still happening and transactions validated
transidvals list * transaction validés list
*)
type_synonym transBdd = "transidvals list * transaction list" (* ((c,m,i),amc,amm,isAvailable)list * ((c,m,i),am)list *)

(*****************UPDATE TRANSIDVAL LIST******************)

(* updateValsPay
RETREIVE: vals to update AND nat to affect to it
RETURN:   vals update if it's allowed
*)
fun updateValsPay :: "vals \<Rightarrow> nat \<Rightarrow> vals"
where
"updateValsPay None n = (Some n)"|
"updateValsPay (Some v) n = (if v \<ge> n then (Some v) else (Some n))"

(* updateValsAck
RETREIVE: vals to update AND nat to affect to it
RETURN:   vals update if it's allowed
*)
fun updateValsAck :: "vals \<Rightarrow> nat \<Rightarrow> vals"
where
"updateValsAck None n = (Some n)"|
"updateValsAck (Some v) n = (if v \<le> n then (Some v) else (Some n))"

(* updateTransidvalsPay
RETREIVE: transidvals to update AND nat to affect to the pay_amount
RETURN:   transidvals updated with the pay_amount
*)
fun updateTransidvalsPay :: "transidvals \<Rightarrow> nat \<Rightarrow> transidvals"
where
"updateTransidvalsPay (transid, pay , ack, test) n = (if test then (transid, (updateValsPay pay n), ack, test)
                                                              else (transid, pay , ack, test))"

(* updateTransidvalsAck
RETREIVE: transidvals to update AND nat to affect to the sell_amount
RETURN:   transidvals updated with the pay_amount
*)
fun updateTransidvalsAck :: "transidvals \<Rightarrow> nat \<Rightarrow> transidvals"
where
"updateTransidvalsAck (transid, pay , ack, test) n = (if test then (transid, pay, (updateValsAck ack n), test)
                                                              else (transid, pay , ack, test))"

(* updateTransidvalsCancel
RETREIVE: transidvals to update
RETURN:   transidvals updated to be cancelled
*)
fun updateTransidvalsCancel :: "transidvals  \<Rightarrow> transidvals"
where
"updateTransidvalsCancel (transid, pay , ack, test) = (transid, pay, ack, False)"

(* updateTransidvalsListPay
RETREIVE: transid to modify AND nat to affect to the pay_amount AND in transidvals list to update
RETURN:   transidvlas list updated with the pay_amount
*)
fun updateTransidvalsListPay :: " transidvals list \<Rightarrow> transid \<Rightarrow> nat \<Rightarrow> transidvals list"
where
"updateTransidvalsListPay [] transid n = (transid, (Some n), None, True)#[]"|
"updateTransidvalsListPay ((htransid , hamc, hamm, hisAvailable)#t) transid n =
        (if htransid = transid
          then (updateTransidvalsPay (htransid , hamc, hamm, hisAvailable) n)#t
          else (htransid , hamc, hamm, hisAvailable)#(updateTransidvalsListPay t transid n)
        )"

(* updateTransidvalsListAck
RETREIVE: transid to modify AND nat to affect to the sell_amount AND in transidvals list to update
RETURN:   transivals list updated with the pay_amount
*)
fun updateTransidvalsListAck :: " transidvals list \<Rightarrow> transid \<Rightarrow> nat \<Rightarrow> transidvals list"
where
"updateTransidvalsListAck [] transid n =  (transid, None, (Some n), True)#[]"|
"updateTransidvalsListAck ((htransid , hamc, hamm, hisAvailable)#t) transid n =
        (if htransid = transid
          then (updateTransidvalsAck (htransid , hamc, hamm, hisAvailable) n)#t
          else (htransid , hamc, hamm, hisAvailable)#(updateTransidvalsListAck t transid n)
        )"

(* updateTransidvalsListCancel
RETREIVE: transid to block AND in transBdd to update
RETURN:   transBdd updated with the pay_amount
*)
fun updateTransidvalsListCancel :: " transidvals list \<Rightarrow> transid \<Rightarrow> transidvals list"
where
"updateTransidvalsListCancel [] transid = (transid, None, None, False)#[]"|
"updateTransidvalsListCancel ((htransid , hamc, hamm, hisAvailable)#t) transid =
        (if htransid = transid
          then (updateTransidvalsCancel (htransid , hamc, hamm, hisAvailable))#t
          else (htransid , hamc, hamm, hisAvailable)#(updateTransidvalsListCancel t transid)
        )"

(***********************MAINTAIN TRANSACTION LIST*****************************)

(*isNotInTransaction
RETRIEVE:  transid to test AND transaction to search in
RETURN: bool True if transid not in transaction
*)
fun isNotInTransaction :: "transid \<Rightarrow> transaction list \<Rightarrow> bool"
where
"isNotInTransaction transid [] = True"|
"isNotInTransaction transid ((htransid, hn)#ttr) = (if (htransid = transid)
                                                    then False
                                                    else (isNotInTransaction transid ttr))"

(*validable
RETRIEVE:  transidvals to test if need to be validate
RETURN: bool
*)
fun validable :: "transidvals \<Rightarrow> transaction list \<Rightarrow> bool"
where
"validable (transid, (Some amc), (Some amm), isAvailable) transaction = (isAvailable \<and> (amc \<ge> amm) \<and> (amc\<noteq>0) \<and> (isNotInTransaction transid transaction))"|
"validable _ _ = False"

(*validate
RETRIEVE:  transidvals to validate AND transaction
RETURN: transaction updated
*)
fun validate :: "transidvals \<Rightarrow> transaction list \<Rightarrow> transaction list"
where
"validate (transid, (Some amc), (Some amm), isAvailable) transaction = (transid, amc)#transaction"|
"validate _ transaction = transaction"

(*keepheader
RETRIEVE:  transidvals to keep AND transBdd
RETURN: transBdd
*)
fun keepHeader :: "transidvals \<Rightarrow> transBdd \<Rightarrow> transBdd"
where
"keepHeader keeptrans (transidval, transaction) = ((keeptrans#transidval),transaction)"

(*keepheaderSnd
RETRIEVE:  transaction to keep AND transBdd
RETURN: transBdd
*)
fun keepHeaderSnd :: "transaction \<Rightarrow> transBdd \<Rightarrow> transBdd"
where
"keepHeaderSnd keeptrans (transidval, transaction) = (transidval,(keeptrans#transaction))"

(*updateTransaction
RETRIEVE: current transidvals List AND transactions list to update
RETURN: proper transBdd
*)
fun updateTransaction :: "transidvals list \<Rightarrow> transaction list \<Rightarrow> transBdd"
where
"updateTransaction [] transaction = ([], transaction)"|
"updateTransaction (htransidvals#ttransidvals) transaction = (if (validable htransidvals transaction)
                                                                 then (updateTransaction ttransidvals (validate htransidvals transaction))
                                                                 else (keepHeader htransidvals (updateTransaction ttransidvals transaction))
                                                                )
"

(*updateTransactionCancel
RETRIEVE: transid AND transactions list to update
RETURN: proper transBdd
*)
fun updateTransactionCancel :: "transid \<Rightarrow> transidvals list \<Rightarrow> transaction list \<Rightarrow> transBdd"
where
"updateTransactionCancel transid transidvals [] = (transidvals, [])"|
"updateTransactionCancel transid transidvals ((htransid,hn)#ttransaction) = (if (htransid = transid)
                                                                        then (transidvals, ttransaction)
                                                                        else (keepHeaderSnd (htransid,hn) (updateTransactionCancel transid transidvals ttransaction)))
"

(*updateTransactionBdd
RETRIEVE: transBdd to update
RETURN: proper transBdd
*)
fun updateTransactionBdd :: "transBdd \<Rightarrow> transBdd"
where
"updateTransactionBdd (transidvals, transaction) = (updateTransaction transidvals transaction)"

(*updateTransactionBddCancel
RETRIEVE: transBdd to update
RETURN: proper transBdd
*)
fun updateTransactionBddCancel :: "transid \<Rightarrow> transBdd \<Rightarrow> transBdd"
where
"updateTransactionBddCancel transid (transidvals, transaction) = (updateTransactionCancel transid transidvals transaction)"

(*tidValidated
RETRIEVE: a transid and current validated transaction
RETURN: if the transid already have been validated
*)
fun tidValidated :: "transid \<Rightarrow> transaction list \<Rightarrow> bool"
where
"tidValidated _ [] = False"|
"tidValidated transid ((htransid,hvalue)#ttrans) = (if (transid = htransid) then True else (tidValidated transid ttrans))"

(**********************FINAL FONCTIONS***************************)

(* traiterMessage
RETREIVE: message to process AND transBdd
RETURN:   updated transBdd
*)
fun traiterMessage :: "message \<Rightarrow> transBdd \<Rightarrow> transBdd"
where
"traiterMessage (Pay tid n) (transidvalsList, transaction) =(if \<not>(tidValidated tid transaction) then (updateTransactionBdd ((updateTransidvalsListPay transidvalsList tid n ), transaction) ) else (transidvalsList, transaction))"|
"traiterMessage (Ack tid n) (transidvalsList, transaction) =(if \<not>(tidValidated tid transaction) then (updateTransactionBdd ((updateTransidvalsListAck transidvalsList tid n ), transaction) ) else (transidvalsList, transaction))"|
"traiterMessage (Cancel tid) (transidvalsList, transaction) =(updateTransactionBddCancel tid ((updateTransidvalsListCancel transidvalsList tid), transaction))"

(* traiterMessageList
RETREIVE: message list to process AND transBdd
RETURN:   updated transBdd
*)
fun traiterMessageList :: "message list \<Rightarrow> transBdd \<Rightarrow> transBdd"
where
"traiterMessageList [] tBdd = tBdd"|
"traiterMessageList (hmessage#tmessage) tBdd = (traiterMessageList tmessage (traiterMessage hmessage tBdd))"

(* export
RETREIVE: transBdd
RETURN:  transaction list
*)
fun export :: "transBdd \<Rightarrow> transaction list"
where
"export (tIdV, tr) = tr"

(****************************TESTING*****************************************)

(* ----- Exportation en Scala (Isabelle 2014) -------*)

(* Directive d'exportation *)
export_code export traiterMessage in Scala

(****************************PROPERTIES**************************************)

(*Lemme 1: member of transaction > 0           *)
lemma lem1:"(List.member (export (traiterMessageList messages ([],[]))) (transid, a)) \<longrightarrow> \<not>(a\<le>0)"
nitpick [timeout=2000]
quickcheck [narrowing, timeout=2000, size=9]
sorry

(*Lemme 2: only one occurence of transid in transaction*)

(*lemme 3: even validated transaction can be discard*)
lemma lem3:"\<not>((List.member (export (traiterMessage (Cancel transid) (traiterMessageList messages ([],[])))) (transid,n)))"
nitpick [timeout=2000]
quickcheck [narrowing, timeout=2000, size=9]
sorry

(*lemme 4: every canceled transaction cannot be validated*)
lemma lem4:" (messages = (head@(Cancel transid)#tail)) \<longrightarrow> \<not>(List.member (export (traiterMessageList messages ([],[]))) (transid,n))"
nitpick [timeout=2000]
quickcheck [narrowing, timeout=2000, size=9]
sorry

(*lemme 5: Validation of a transaction mean there was a Pay and Ack message with amc\<ge>amm and not canceled*)
lemma lem5:" ((List.member messages (Pay transid amc))\<and>(List.member messages (Ack transid amm))\<and>\<not>(List.member messages (Cancel transid))\<and>(amc \<ge> amm)\<and>(amc>0))
               \<longrightarrow> (List.member (export (traiterMessageList messages ([],[]))) (transid,a)) \<longrightarrow> (a\<ge>amm)"
nitpick [timeout=2000]
quickcheck [narrowing, timeout=2000, size=9]
sorry

(*lemme 6: every validated transaction must be a result of a Pay and Ack message where amc\<ge>amm*)
fun getMinAmm :: "message list \<Rightarrow> transid  \<Rightarrow> nat  \<Rightarrow> nat"
where
"getMinAmm [] transid  n = n"|
"getMinAmm ((Ack tid amm)#tmessage) transid n =(if (transid = tid)
                                                  then
                                                     (if amm<n
                                                       then (getMinAmm tmessage transid amm)
                                                       else (getMinAmm tmessage transid n))
                                                  else (getMinAmm tmessage transid n))"|
"getMinAmm (hmessage#tmessage) transid n = (getMinAmm tmessage transid n)"

fun getMaxAmc :: "message list \<Rightarrow> transid  \<Rightarrow> nat  \<Rightarrow> nat"
where
"getMaxAmc [] transid  n = n"|
"getMaxAmc ((Pay tid amm)#tmessage) transid n =(if (transid = tid)
                                                  then
                                                     (if amm>n
                                                       then (getMaxAmc tmessage transid amm)
                                                       else (getMaxAmc tmessage transid n))
                                                  else (getMaxAmc tmessage transid n))"|
"getMaxAmc (hmessage#tmessage) transid n = (getMaxAmc tmessage transid n)"

fun getMinAmmInit :: "message list \<Rightarrow> transid \<Rightarrow> nat option"
where
"getMinAmmInit [] _ = None"|
"getMinAmmInit ((Ack tid amm)#tmessage) transid =(if (transid = tid) then (Some (getMinAmm tmessage tid amm)) else (getMinAmmInit tmessage transid))"|
"getMinAmmInit (hmessage#tmessage) transid = (getMinAmmInit tmessage transid)"

fun getMaxAmcInit :: "message list \<Rightarrow> transid \<Rightarrow> nat option"
where
"getMaxAmcInit [] _ = None"|
"getMaxAmcInit ((Pay tid amc)#tmessage) transid =(if (transid = tid) then (Some (getMaxAmc tmessage tid amc)) else (getMaxAmcInit tmessage transid))"|
"getMaxAmcInit (hmessage#tmessage) transid = (getMaxAmcInit tmessage transid)"

lemma lem6:"( (ammOpt = (getMinAmmInit messages transid)) \<and> (ammOpt = (Some ammn)) \<and> (amm = ammn )) \<longrightarrow>
              (List.member (export (traiterMessageList messages ([],[]))) (transid,amc))
              \<longrightarrow>((List.member messages (Pay transid amc)) \<and> (List.member messages (Ack transid amm))) \<longrightarrow> (amc\<ge>amm)"
nitpick [timeout=2000]
quickcheck [narrowing, timeout=2000, size=9]
sorry

(*lemme 7: every new propositions that doesn't fit bargaining logic are forgot: client expectation have to go up and seller goes down*)

(*Client side*)
lemma lem71:"((messages = (head@(Pay transid n)#tail)) \<and> (amcOpt = (getMaxAmcInit messages transid)) \<and> (amcOpt = (Some amcn)) \<and> (amc = amcn)  \<and> (a\<le>amc) \<and> (tBdd = (traiterMessageList messages ([],[])) ))
               \<longrightarrow> (tBdd = (traiterMessage (Pay transid a) tBdd))"
nitpick [timeout=2000]
quickcheck [narrowing, timeout=2000, size=9]
sorry

(*Marchant side*)
lemma lem72:"((messages = (head@(Ack transid n)#tail)) \<and> (ammOpt = (getMinAmmInit messages transid)) \<and> (ammOpt = (Some ammn)) \<and> (amm = ammn) \<and> (a\<ge>amm) \<and> (tBdd = (traiterMessageList messages ([],[])) ))
               \<longrightarrow> (tBdd = (traiterMessage (Ack transid a) tBdd))"
nitpick [timeout=2000]
quickcheck [narrowing, timeout=2000, size=9]
sorry

(*lemme 8: every validated transaction cannot be renegociated. The price am doesn't change*)
lemma lem8:"(List.member (export (traiterMessageList messages ([],[]))) (transid,n))
            \<longrightarrow> (\<not>(List.member addMess (Cancel transid))) \<longrightarrow> (List.member (export (traiterMessageList (messages@addMess) ([],[]))) (transid,n)) "
nitpick [timeout=2000]
quickcheck [narrowing, timeout=2000, size=9]
sorry

(*lemme 9: the amount in validated transaction is equal to the price proposed by the client*)
lemma lem9:"(List.member (export (traiterMessageList messages ([],[]))) (transid,n)) \<longrightarrow> ((Some n) = (getMaxAmcInit messages transid))"
nitpick [timeout=2000]
quickcheck [narrowing, timeout=2000, size=9]
sorry

end


theory TeslDenotationalArchiWrong

imports TeslDenotationalArchi

begin

(*
  FIXME:  no link between timep and index in clocks
          so no way to prove that (index c) < rank r\<^sub>1 implies
          that the time of c is in the first component of the time structure.
*)
lemma clock_proj\<^sub>1:
  assumes "ticks c (hamlet (r\<^sub>1 \<times>\<^sub>r\<^sub>u\<^sub>n r\<^sub>2) n)"
  and     "(index c) < rank r\<^sub>1"
  shows   "\<exists>c\<^sub>0. c = shift\<^sub>1 c\<^sub>0 r\<^sub>1"
proof -
  from assms have "\<exists>f. c = (f \<circ> fst, index c)" sorry
  from this obtain f where "c = (f \<circ> fst, index c)" by blast
  hence "c = shift\<^sub>1 (f, index c) r\<^sub>1" unfolding shift\<^sub>1_def by auto
  thus ?thesis by blast
qed

lemma clock_proj\<^sub>2:
  assumes "ticks c (hamlet (r\<^sub>1 \<times>\<^sub>r\<^sub>u\<^sub>n r\<^sub>2) n)"
  and     "(index c) \<ge> rank r\<^sub>1"
  shows   "\<exists>c\<^sub>0. c = shift\<^sub>2 c\<^sub>0 r\<^sub>1"
proof -
  from assms(2) have "\<exists>i\<^sub>0. (index c) = i\<^sub>0 + rank r\<^sub>1" by presburger
  from this obtain i\<^sub>0 where i0prop:"(index c) = i\<^sub>0 + rank r\<^sub>1" by blast
  from assms have "\<exists>f. c = (f \<circ> snd, index c)" sorry
  from this obtain f where "c = (f \<circ> snd, index c)" by blast
  with i0prop have "c = shift\<^sub>2 (f, i\<^sub>0) r\<^sub>1" unfolding shift\<^sub>2_def by auto
  thus ?thesis by blast
qed

lemma
  assumes "ticks (c::('a::orderedrank \<times> 'b::orderedrank, 'c)\<H>) (hamlet ((r\<^sub>1::'a run) \<times>\<^sub>r\<^sub>u\<^sub>n (r\<^sub>2::'b run)) n)"
  and     "index c < rank r\<^sub>1"
  shows   "\<exists>sc. c = shift\<^sub>1 sc r\<^sub>1 \<and> ticks sc (hamlet r\<^sub>1 n)"
proof -
  from assms have "(hamlet (r\<^sub>1 \<times>\<^sub>r\<^sub>u\<^sub>n r\<^sub>2) n)!(index c)" unfolding ticks_def by metis
  hence "((hamlet r\<^sub>1 n)@(hamlet r\<^sub>2 n))!(index c)" by (simp add: hamlet_prod_hamlet)
  with assms(2) have *:"(hamlet r\<^sub>1 n)!(index c)" by (simp add: nth_append rank_any_hamlet)
  from clock_proj\<^sub>1[OF assms] obtain sc where scprop:"c = shift\<^sub>1 sc r\<^sub>1" by blast
  with * have "(hamlet r\<^sub>1 n)!(index sc)" unfolding shift\<^sub>1_def by simp
  moreover from assms(2) have "index sc < rank r\<^sub>1" by (simp add: scprop shift\<^sub>1_def)
  ultimately have "ticks sc (hamlet r\<^sub>1 n)" unfolding ticks_def by (simp add: rank_any_hamlet)
  with scprop show ?thesis by blast
qed

lemma
  assumes "ticks (c::('a::orderedrank \<times> 'b::orderedrank, 'c)\<H>) (hamlet ((r\<^sub>1::'a run) \<times>\<^sub>r\<^sub>u\<^sub>n (r\<^sub>2::'b run)) n)"
  and     "index c \<ge> rank r\<^sub>1"
  shows   "\<exists>sc. c = shift\<^sub>2 sc r\<^sub>1 \<and> ticks sc (hamlet r\<^sub>2 n)"
proof -
  from assms have "index c < length (hamlet (r\<^sub>1 \<times>\<^sub>r\<^sub>u\<^sub>n r\<^sub>2) n) \<and> (hamlet (r\<^sub>1 \<times>\<^sub>r\<^sub>u\<^sub>n r\<^sub>2) n)!(index c)"
    unfolding ticks_def by metis
  hence "index c < rank r\<^sub>1 + rank r\<^sub>2 \<and> ((hamlet r\<^sub>1 n)@(hamlet r\<^sub>2 n))!(index c)"
    by (simp add: hamlet_prod_hamlet rank_any_hamlet)
  with assms(2) have *:"(index c - rank r\<^sub>1) < rank r\<^sub>2 \<and> (hamlet r\<^sub>2 n)!(index c - rank r\<^sub>1)"
    by (auto simp add: nth_append rank_any_hamlet)
  from clock_proj\<^sub>2[OF assms] obtain sc where scprop:"c = shift\<^sub>2 sc r\<^sub>1" by blast
  with * have "index sc < rank r\<^sub>2 \<and> (hamlet r\<^sub>2 n)!(index sc)" unfolding shift\<^sub>2_def by simp
  hence "ticks sc (hamlet r\<^sub>2 n)" unfolding ticks_def by (simp add: rank_any_hamlet)
  with scprop show ?thesis by blast
qed

end