theory LiveDemo02
  imports 
    Main
begin

section \<open>Eigenvariable Condition\<close>

lemma "\<forall> y. y = x"
proof (rule allI)
  fix y
  show "y = x" 
    oops

lemma "\<forall> y. y = x"
proof (rule allI)
  fix z
  show "z = x" (* we can choose a different name than y *)
    oops

text \<open>The upcoming examples just show that it is not possible to cheat.
  They are definitely not good style!\<close>

lemma "\<forall> y. y = x"
proof (rule allI)
  fix x
  show "x = x" (* it is not allowed to choose x *)
    oops

lemma "\<forall> y. y = x"
proof (rule allI)
  let ?blue_x = x (* let can be used to abbreviate terms within proofs *)
  fix x 
  show "x = ?blue_x" (* orange x \<noteq> blue x *)
    using refl[of x] refl[of ?blue_x]
    oops

lemma "\<forall> x y. x = y"
proof (rule allI)
  fix x :: 'a
  let ?orange_x = x
  show "\<forall>y. x = y" 
  proof (rule allI)
    fix x  
    show "?orange_x = x" (* automatic renaming *)
    oops



section \<open>The rule method (in introduction mode)\<close>

lemma "x < 5 \<Longrightarrow> x < 3 \<and> x < 2" 
proof (rule conjI)
  oops

lemma "\<exists> y. 5 < y"  
proof (rule exI)
  oops




section \<open>Equality of Terms\<close>

thm refl (* reflexivity of equality: t = t *)

text \<open>\<alpha>-conversion is implicitly done\<close>

lemma alpha: "(\<forall> x. P x) = (\<forall> y. P y)" by (rule refl)

text \<open>\<beta>-reduction "(\<lambda> x. t) s \<longrightarrow>\<beta>  t [ x / s]" is implicitly done\<close>
lemma beta: "(\<lambda> x. P (x + x)) y = P (y + y)" by (rule refl)

text \<open>\<eta>-expansion "f = (\<lambda> x. f x)" if f has function-type 
  is implicitly invoked\<close>
lemma eta: "(\<lambda> x. f x) = f" by (rule refl)


section \<open>Drinker's paradox\<close>

thm excluded_middle ccontr

text \<open>elimination rules\<close>
thm disjE conjE exE allE impE notE
thm disjE

text \<open>introduction rules\<close>
thm disjI1 disjI2 conjI exI allI impI notI

lemma drinkers_paradox: "\<exists> p. drinks p \<longrightarrow> (\<forall> x. drinks x)" 
proof -
  have "\<not> (\<exists> p. \<not> drinks p) \<or> (\<exists> p. \<not> drinks p)" 
    by (rule excluded_middle)
  from this show "\<exists> p. drinks p \<longrightarrow> (\<forall> x. drinks x)"
  proof
    {
      assume "\<exists>p. \<not> drinks p" 
      from this show ?thesis
      proof 
        fix p
        assume ndp: "\<not> drinks p" 
        show ?thesis
        proof (intro allI exI impI)
          fix x
          assume "drinks p"           
          from ndp this show "drinks x" ..
        qed
      qed
    }
    {
      assume a: "\<nexists>p. \<not> drinks p"   
      show ?thesis
      proof (intro exI impI allI)
        fix x
        show "drinks x" 
        proof (rule ccontr)
          assume "\<not> drinks x" 
          from this have "\<exists> x. \<not> drinks x" ..
          from a this show False ..
        qed
      qed
    }
  qed
qed
    
lemma drinkers_paradox_new: "\<exists> p. drinks p \<longrightarrow> (\<forall> x. drinks x)" 
proof -
  {
    fix p
    assume "\<not> drinks p" 
    from this have "drinks p \<longrightarrow> (\<forall> x. drinks x)" by auto
    from this have ?thesis by auto
  }
  from this have case1: "\<And> p. \<not> drinks p \<Longrightarrow> ?thesis" by auto

  {
    assume "\<forall> p. drinks p" 
    from this have ?thesis by auto
  }
  from case1 this show ?thesis by auto
qed

thm drinkers_paradox_new[of "\<lambda> x. x < 5"]

lemma "\<exists> p. drinks p \<longrightarrow> (\<forall> x. drinks x)" by auto


(* - there are other proofs with many comments in Demo02.thy
   - this file just contains the proofs of the drinkers paradox 
     that have been developed during the lecture *)

end