theory Demo = Main: (* a simple backward step: *) lemma "A & B" apply(rule conjI) oops; (* a simple backward proof: *) lemma "B & A --> A & B" apply(rule impI) apply(rule conjI) apply(rule conjE) apply(assumption) apply(rule conjE) apply(assumption) apply(assumption) apply(rule conjE) apply(assumption) apply(assumption) done; (* a shorter version: *) lemma "B & A --> A & B" apply(rule impI) apply(rule conjE) apply(assumption) apply(rule conjI) apply(assumption) apply(assumption) done; (* still shorter, using elim-resolution: *) lemma "B & A --> A & B" apply(rule impI) apply(erule conjE) apply(rule conjI) apply(assumption) apply(assumption) done; (* automatically: *) lemma "B & A --> A & B" apply(blast) (* works as well: apply(fast) apply(auto) *) done; (* more hand-examples: *) lemma "A&B | C ==> (A|C)&(B|C)" apply(erule disjE) apply(erule conjE) apply(rule conjI) apply(rule disjI1) apply(assumption) (* quicker: *) apply(erule disjI1) apply(rule conjI) apply(erule disjI2) apply(erule disjI2) done; lemma "[| A; A-->B; B-->C |] ==> C" apply(erule impE) apply(assumption) apply(erule impE) apply(assumption) apply(assumption) done; lemma "((P --> Q) --> P) --> P" apply(rule impI) apply(rule classical) apply(erule impE) apply(rule impI) apply(erule notE) apply assumption apply assumption done; (* explicit case distinctions: *) lemma "((P --> Q) --> P) --> P" apply(case_tac P) apply(simp) apply(simp) done; (* explicit backtracking *) lemma "[| P & Q; A & B |] ==> A" apply(erule conjE) back apply(assumption) (* UGLY! NOT ALLOWED IN FINAL SOLUTION *) oops; (* implict backtracking *) lemma "[| P & Q; A & B |] ==> A" apply(erule conjE, assumption) done; (*** Basic rules ***) (* \ *) thm conjI conjE conjunct1 conjunct2; (* \ *) thm disjI1 disjI2 disjE; (* \ *) thm impI impE mp; (* = (iff) *) thm iffI iffE iffD1 iffD2; (* \ *) thm notI notE; (* Contradictions *) thm FalseE ccontr classical; (* Contrapositives *) thm contrapos_nn contrapos_pp contrapos_np; end