theory LiveDemo03 imports Main begin section \Exercise Discussion\ lemma bool_diffE: "b = (\ b) \ P" proof - assume id: "b = (\ b)" have "\ b \ b" .. from this have False proof { assume b thm subst from id this have "\ b" by (rule subst) from this \b\ show False .. } { assume "\ b" from id this have b .. from \\ b\ this show False .. } qed from this show P .. qed section \Finding Theorems and Constants\ find_theorems (* by far too many results *) find_theorems "_ * (_ + _) = _" (* find distributive law *) find_theorems "?x * ?x = _" (* use same value *) find_theorems "_ \ _" (* too many results *) find_theorems "_ \ _" name: HOL (* restrict by name *) find_theorems (100) "_ \ _" name: HOL (* show up to 100 results *) find_theorems "_ \ _" name: HOL -"_ \ _" -"_ \ _" -All -Ex (* restrict by exclusion *) find_consts "?'a \ ?'a \ _ list" term "upt 0 100" value "[0..100]" section \Drinker's Paradox -- Tuning Proofs\ text \previous version copied from Demo02\ lemma drinkers_paradox_v2: "\ p. drinks p \ (\ x. drinks x)" proof - { assume "\ x. \ drinks x" then obtain x where nex: "\ drinks x" by auto have ?thesis proof from nex show "drinks x \ (\y. drinks y)" by auto qed } moreover { assume "\ (\ x. \ drinks x)" hence "\ x. drinks x" by auto hence ?thesis by auto } ultimately show ?thesis by auto qed text \Usage of case-analysis on Booleans with cases True/False separated by "next".\ lemma drinkers_paradox_v3: "\ p. drinks p \ (\ x. drinks x)" proof (cases "\ x. \ drinks x") case True then obtain x where "\ drinks x" by auto thus ?thesis by auto next case False then show ?thesis by auto qed text \Omit trivial cases via final method\ lemma drinkers_paradox_v5: "\ p. drinks p \ (\ x. drinks x)" proof (cases "\ x. \ drinks x") case True then obtain x where "\ drinks x" by auto thus ?thesis by auto qed auto (* solve trivial cases by auto after qed *) section \Intro and Elim: apply several introduction / elimination rules\ lemma "A \ (\ x :: nat. B x \ (C \ D x))" proof (intro conjI exI) \ \three subgoals: A, B ?x, C \ D ?x\ show A sorry show "B 5" sorry (* here we choose witness 5 *) show "C \ D 5" sorry (* no choice of witness anymore *) qed lemma True (* True is used as dummy property *) proof - fix A B C D assume "\ x :: nat. A \ (B x \ C x)" hence D proof (elim exE conjE disjE) (* apply multiple elimination rules *) (* inspect proof goals at this point *) oops section \Case-Analysis and Induction\ text \A copy of the list datatype to illustrate print-theorems\ datatype 'a ls = Empty | Con 'a "'a ls" print_theorems thm ls.induct thm ls.simps text \This datatype definition proves a lot of theorems for you, as can be seen by print_theorems that is used directly after some definition.\ thm list.exhaust (* case analysis on lists *) thm list.induct (* induction on lists *) thm list.simps (* simplification rules for list-constructors *) fun app :: "'a list \ 'a list \ 'a list" where "app [] ys = ys" | "app (x # xs) ys = x # (app xs ys)" print_theorems fun reverse :: "'a list \ 'a list" where "reverse [] = []" | "reverse (x # xs) = app (reverse xs) ([x])" text \Auxiliary lemmas obtained while trying to prove @{prop "reverse (reverse xs) = xs"}\ lemma app_Nil[simp]: "app xs [] = xs" by (induction xs) auto lemma app_assoc: "app (app xs ys) zs = app xs (app ys zs)" by (induction xs) auto lemma rev_app: "reverse (app xs ys) = app (reverse ys) (reverse xs)" proof (induction xs) case (Cons x xs) then show ?case by (auto simp: app_assoc) qed auto lemma rev_rev[simp]: "reverse (reverse xs) = xs" proof (induction xs) case (Cons x xs) from Cons show "reverse (reverse (x # xs)) = x # xs" by (auto simp: rev_app) qed auto text \What follows is the final proof of the fact that reversing a list twice results in the input list. The development process of this proof is much more interesting than the final proof and will be given via a live demo in the lecture.\ text \A proof by case-analysis\ fun tail :: "'a list \ 'a list" where "tail [] = []" | "tail (_ # xs) = xs" lemma len_tail: "length (tail xs) = length xs - 1" proof (cases xs) case Nil then show ?thesis by auto next case (Cons x ys) then show ?thesis by auto qed text \An induction proof involving case-analysis\ fun drop_last :: "'a list \ 'a list" where "drop_last (x # y # ys) = x # drop_last (y # ys)" | "drop_last xs = []" thm drop_last.simps (* observe how the second defining equation is handled *) lemma len_drop: "length (drop_last xs) = length xs - 1" proof (induction xs) case (Cons x xs) text \case analysis on xs required to trigger simp-rules of @{const drop_last}.\ show ?case proof (cases xs) case xs: (Cons y ys) text \use different label so that inner Cons (xs = y # ys) does not hide outer Cons (IH)\ with Cons show ?thesis by auto qed auto qed auto end