theory Demo03 imports Main begin section{* Propositional logic *} subsection{* Basic rules *} text{* \<and> *} thm conjI conjE text{* \<or> *} thm disjI1 disjI2 disjE text{* \<longrightarrow> *} thm impI impE subsection{* Examples *} text{* a simple backward step: *} lemma "A \<and> B" thm conjI apply(rule conjI) oops text{* a simple backward proof: *} lemma "B \<and> A \<longrightarrow> A \<and> B" apply(rule impI) apply(erule conjE) apply(rule conjI) apply(assumption) apply(assumption) done lemma "A \<or> B \<longrightarrow> B \<or> A" apply (rule impI) apply (erule disjE) apply (rule disjI2) apply assumption apply (rule disjI1) apply assumption done lemma "\<lbrakk> A \<longrightarrow> B; B \<longrightarrow> C \<rbrakk> \<Longrightarrow> A \<longrightarrow> C" apply (rule impI) apply (erule impE) apply assumption apply (erule impE) apply assumption apply assumption done thm notI notE lemma "\<not>A \<or> \<not>B \<Longrightarrow> \<not>(A \<and> B)" apply (rule notI) apply (erule disjE) apply (erule conjE) apply (erule notE) apply assumption apply (erule conjE) apply (erule notE) apply assumption done text{* Explicit backtracking: *} lemma "\<lbrakk> P \<and> Q; A \<and> B \<rbrakk> \<Longrightarrow> A" apply(erule conjE) back apply(assumption) done text{* Ugly! Avoid in finished proofs. *} text{* Implict backtracking: chaining with , *} lemma "\<lbrakk> P \<and> Q; A \<and> B \<rbrakk> \<Longrightarrow> A" apply(erule conjE, assumption) done text {* Case distinctions *} lemma "P \<or> \<not>P" apply (case_tac "P") oops thm FalseE lemma "(\<not>P \<longrightarrow> False) \<longrightarrow> P" apply (rule impI) apply (case_tac "P") apply assumption apply (erule impE) apply assumption apply (erule FalseE) done -- --------------------------------------- subsection {* more rules *} text{* \<and> *} thm conjunct1 conjunct2 text{* \<or> *} thm disjCI text{* \<longrightarrow> *} thm mp text{* = (iff) *} thm iffI iffE iffD1 iffD2 text{* Equality *} thm refl sym trans text{* \<not> *} thm notI notE text{* Contradictions *} thm FalseE ccontr classical excluded_middle text{* = (iff) *} thm iffI iffE iffD1 iffD2 text{* Equality *} thm refl sym trans text {* defer and prefer *} lemma "(A \<or> A) = (A \<and> A)" apply (rule iffI) defer sorry text{* A warming up exercise: classical propositional logic. *} lemma Pierce: "((A \<longrightarrow> B) \<longrightarrow> A) \<longrightarrow> A" sorry -- -------------------------------------- section {* 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) (* doesn't work 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" *} text {* May not refer to parameters of the goal. *} thm conjI thm conjI [of A B] thm conjI [where Q = "f x"] lemma "\<forall>x. x = x" apply (rule allI) thm refl [where t = x] (* doesn't work apply (rule refl [where t = x]) *) oops 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 -- --------------------------------------------- text {* Attributes *} definition xor :: "bool \<Rightarrow> bool \<Rightarrow> bool" where "xor A B \<equiv> (A \<and> \<not>B) \<or> (\<not>A \<and> B)" lemma xorI [intro!]: "\<lbrakk> \<lbrakk>A; B\<rbrakk> \<Longrightarrow> False; \<not>B \<Longrightarrow> A \<rbrakk> \<Longrightarrow> xor A B" apply (unfold xor_def) apply blast done lemma xorE: "\<lbrakk> xor A B; \<lbrakk>A; \<not>B\<rbrakk> \<Longrightarrow> R; \<lbrakk>\<not>A; B\<rbrakk> \<Longrightarrow> R \<rbrakk> \<Longrightarrow> R" apply (unfold xor_def) apply blast done lemma "xor A A = False" by (blast elim!: xorE) declare xorE [elim!] lemma "xor A B = xor B A" by blast end