theory Demo4 = Main:


text{* A warming up exercise: propositional logic. *}
lemma "(A \<and> (B \<or> C)) \<Longrightarrow> (A \<and> B \<or> C)"
oops

-- {* more rules *}

text{* = (iff) *}
thm iffI iffE iffD1 iffD2

text{* Equality *}
thm refl sym trans

text{* \<not> *}
thm notI notE

text{* True and False *}
thm TrueI FalseE

-- -----------------------------
text {* defer and prefer *}

lemma "(A \<or> A) = (A \<and> A)"
  apply (rule iffI)
  defer  
  sorry


lemma contraposition: 
  "(A \<longrightarrow> B) \<Longrightarrow> (\<not>B \<longrightarrow> \<not>A)"
  sorry


text {* classical, cases *}
   
lemma "(\<not>A \<longrightarrow> B) \<Longrightarrow> (\<not>B \<longrightarrow> A)"
  sorry


lemma Pierce: "((A \<longrightarrow> B) \<longrightarrow> A) \<longrightarrow> A"
  sorry


lemma PnP: "P \<or> \<not>P"
  apply (cases "P")
  oops  


text {* safe and unsafe *}
lemma "A \<and> C \<Longrightarrow> A \<or> B"
  oops


-- ------------------------------------

text {* Quantifier reasoning *}

text{* A successful proof: *}
lemma "\<forall>x. \<exists>y. x = y" 
apply(rule allI)
apply(rule exI)
apply(rule refl)
done


text{* An unsuccessful proof: *}
lemma "\<exists>y. \<forall>x. x = y"
apply(rule exI)
apply(rule allI)
(* Does not work:
apply(rule refl)
*)
oops

text{* Intro and elim resoning: *}
lemma "\<exists>y. \<forall>x. P x y \<Longrightarrow> \<forall>x. \<exists>y. P x y"
(* the safe rules first: *)
apply(rule allI)
apply(erule exE)
(* now the unsafe ones: *)
apply(rule_tac x=y in exI)
apply(erule_tac x=x in allE)
apply(assumption)
done

text{* What happens if an unsafe rule is tried too early: *}
lemma "\<exists>y. \<forall>x. P x y \<Longrightarrow> \<forall>x. \<exists>y. P x y"
apply(rule allI)
apply(rule exI)
apply(erule exE)
apply(erule allE)
(* Fails now:
apply(assumption)
*)
oops

text {* Instantiation in more detail: *}

text{* Instantiating allE: *}
lemma "\<forall>x. P x \<Longrightarrow> P 37"
thm allE
apply (erule_tac x = "37" in allE)
apply assumption
done

text{* Instantiating exI: *}
lemma "\<exists>n. P (f n) \<Longrightarrow> \<exists>m. P m"
apply(erule exE)
thm exI
apply(rule_tac x = "f n" in exI)
apply assumption
done

text{* Instantiation removes ambiguity: *}
lemma "\<lbrakk> A \<and> B; C \<and> D \<rbrakk> \<Longrightarrow> D"
thm conjE
apply(erule_tac P = "C" in conjE)
(* without instantiation, the wrong one is chosen (first) *)
apply assumption
done


text {* Instantiation with "where" and "of" *}

thm conjI
thm conjI [of A B]
thm conjI [where Q = "f x"]

text {* Exercises *}

lemma "\<exists>x. \<forall>y. P x y \<Longrightarrow> \<forall>y. \<exists>x. P x y"
oops

lemma "(\<exists>x. P x) \<longrightarrow> Q \<Longrightarrow> \<forall>x. P x \<longrightarrow> Q" 
oops

lemma "\<exists>x. (P x \<longrightarrow> (\<forall>x. P x))"
oops

-- ----------------------------------------------

text{* Renaming parameters: *}

lemma "\<And>x y z. P x y z"
apply(rename_tac a b)
oops

lemma "\<forall>x. P x \<Longrightarrow> \<forall>x. \<forall>x. P x"
apply(rule allI)
apply(rule allI)
apply(rename_tac X)
apply(erule_tac x=X in allE)
apply assumption
done




text {* Forward reasoning: drule/frule/OF/THEN*}

lemma "A \<and> B \<Longrightarrow> \<not> \<not> A"
thm conjunct1
apply (drule conjunct1)
apply (rule notI)
apply (erule notE)
apply assumption
done


lemma "\<forall>x. P x \<Longrightarrow> P t"
  thm spec
  apply (frule spec)
  apply assumption
  done


thm dvd_add dvd_refl
thm dvd_add [OF dvd_refl]
thm dvd_add [OF dvd_refl dvd_refl]


-- ---------------------------------------------

text {* Epsilon *}

lemma "(\<exists>x. P x) = P (SOME x. P x)"
  apply (rule iffI)
   apply (erule exE)
   apply (rule someI)
   apply assumption
  apply (rule exI)
  apply assumption
  done


text {* Automation *}

lemma "\<forall>x y. P x y \<and> Q x y \<and> R x y"
apply (intro allI conjI)
oops

lemma "\<forall>x y. P x y \<and> Q x y \<and> R x y"
apply clarify
oops

lemma "\<forall>x y. P x y \<and> Q x y \<and> R x y"
apply safe
oops

lemma "\<exists>y. \<forall>x. P x y \<Longrightarrow> \<forall>x. \<exists>y. P x y"
apply blast
done

lemma "\<exists>y. \<forall>x. P x y \<Longrightarrow> \<forall>x. \<exists>y. P x y"
apply fast
done


end
