theory Demo02 imports Main begin section \Eigenvariable Condition\ lemma "\ y. y = x" proof (rule allI) fix y show "y = x" oops lemma "\ y. y = x" proof (rule allI) fix z show "z = x" (* we can choose a different name than y *) oops text \The upcoming examples just show that it is not possible to cheat. They are definitely not good style!\ lemma "\ y. y = x" proof (rule allI) fix x show "x = x" (* it is not allowed to choose x *) oops lemma "\ 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 \ blue x *) using refl[of x] refl[of ?blue_x] oops lemma "\ x y. x = y" proof (rule allI) fix x :: 'a let ?orange_x = x show "\y. x = y" proof (rule allI) fix x show "?orange_x = x" (* automatic renaming *) oops section \The rule method (in introduction mode)\ lemma "x < 5 \ x < 3 \ x < 2" proof (rule conjI) oops lemma "\ y. 5 < y" proof (rule exI) oops section \Equality of Terms\ thm refl (* reflexivity of equality: t = t *) text \\-conversion is implicitly done\ lemma alpha: "(\ x. P x) = (\ y. P y)" by (rule refl) text \\-reduction "(\ x. t) s \\ t [ x / s]" is implicitly done\ lemma beta: "(\ x. P (x + x)) y = P (y + y)" by (rule refl) text \\-expansion "f = (\ x. f x)" if f has function-type is implicitly invoked\ lemma eta: "(\ x. f x) = f" by (rule refl) section \Drinker's paradox\ lemma drinkers_paradox_v1: "\ p. drinks p \ (\ x. drinks x)" proof - have "\ (\ x. \ drinks x) \ (\ x. \ drinks x)" by (rule excluded_middle) from this show "\ p. drinks p \ (\ x. drinks x)" proof (rule disjE) { assume "\ x. \ drinks x" from this show ?thesis proof (rule exE) fix y assume ny: "\ drinks y" show ?thesis proof (rule exI) show "drinks y \ (\x. drinks x)" proof (rule impI) assume "drinks y" from ny this show "\x. drinks x" by (rule notE) qed qed qed } { assume "\ (\ x. \ drinks x)" show ?thesis proof (intro exI impI allI) fix x show "drinks x" proof (rule ccontr) assume "\ drinks x" from this have "\ x. \ drinks x" by (rule exI) from \\ (\ x. \ drinks x)\ this show False by (rule notE) qed qed } qed qed lemma drinkers_paradox_v1_with_comments: "\ p. drinks p \ (\ x. drinks x)" proof - have "\ (\ x. \ drinks x) \ (\ x. \ drinks x)" by (rule excluded_middle) from this show "\ p. drinks p \ (\ x. drinks x)" proof (rule disjE) (* rule can also apply elimination rules *) thm disjE (* ?P \ ?Q \ (?P \ ?R) \ (?Q \ ?R) \ ?R *) (* at this point we get two proof obligations, since they use different assumptions we restrict the scope of the assumptions via raw proof blocks *) term ?thesis { assume "\ x. \ drinks x" from this show ?thesis (* don't copy statement, but use ?thesis *) proof (rule exE) fix y (* we freely choose a name *) assume ny: "\ drinks y" (* we label this assumption *) show ?thesis proof (rule exI) (* here we get a schematic variable ?p in the proof obligation, this means that we can choose the witness. We do this by just typing the corresponding term, i.e., ?p = y in the upcoming proof *) show "drinks y \ (\x. drinks x)" proof (rule impI) assume "drinks y" from ny this show "\x. drinks x" by (rule notE) qed qed qed } (* here the second part of the exE-rule starts *) { assume "\ (\ x. \ drinks x)" show ?thesis proof (intro exI impI allI) (* intro applies several introd. rules *) fix x (* we just ignore the assumption "drinks ?p" *) show "drinks x" proof (rule ccontr) assume "\ drinks x" from this have "\ x. \ drinks x" by (rule exI) (* in the following line we refer to the assumption literally *) from \\ (\ x. \ drinks x)\ this show False by (rule notE) qed qed } qed qed text \After finalizing the proof, the free variable @{term drinks} becomes schematic, so it is now universally quantified. We can easily instantiate schematic variables in theorems via of:\ thm drinkers_paradox_v1[of is_running] thm drinkers_paradox_v1[of even] thm drinkers_paradox_v1[of "\ x. x \ 5"] text \In the proof above no automation was used, but just basic proof rules have been applied. For this you need to know the names of the basic proof rules such as the following ones:\ thm excluded_middle ccontr text \elimination rules\ thm disjE conjE exE allE impE notE text \introduction rules\ thm disjI1 disjI2 conjI exI allI impI notI text \In the following proof we build raw proof blocks that do not correspond to the goal statement, but just state intermediate facts, and we use automation via "auto" instead of just applying all basic rules.\ lemma drinkers_paradox_v2: "\ p. drinks p \ (\ x. drinks x)" proof - { assume "\ x. \ drinks x" from this obtain x where nex: "\ drinks x" by auto have ?thesis proof from nex show "drinks x \ (\y. drinks y)" by auto qed } from this have part1: "(\ x. \ drinks x) \ ?thesis" by auto { assume "\ (\ x. \ drinks x)" from this have "\ x. drinks x" by auto from this have ?thesis by auto } from this have part2: "\ (\ x. \ drinks x) \ ?thesis" by auto from part1 part2 show ?thesis by auto qed lemma drinkers_paradox_v2_with_comments: "\ p. drinks p \ (\ x. drinks x)" proof - { (* we just assume that we treat one of the cases *) assume "\ x. \ drinks x" (* get the existential witness *) from this obtain x where nex: "\ drinks x" by auto have ?thesis (* we cannot write "show ?thesis" in the previous line, since we assumed the existential statement. "show" is only permitted if this would finish a proof obligation by the surrounding proof-qed block *) proof (* standard proof method is exI, since goal is of shape \ x. P x *) (* in the following line we choose the existential witness: ?p = x *) from nex show "drinks x \ (\y. drinks y)" by auto qed } from this have part1: "(\ x. \ drinks x) \ ?thesis" by auto (* now we have solved one part of the proof *) { assume "\ (\ x. \ drinks x)" from this have "\ x. drinks x" by auto from this have ?thesis by auto } from this have part2: "\ (\ x. \ drinks x) \ ?thesis" by auto (* finally prove the lemma from both parts *) from part1 part2 show ?thesis by auto (* here the automation will trigger the case-analysis *) qed text \Actually the drinker's paradox is so simple, that automation can do it on its own.\ lemma drinkers_paradox_v3: "\ p. drinks p \ (\ x. drinks x)" by auto end