theory LiveDemo06 imports Main HOL.Rat (* import rational numbers *) begin section \Methods\ text \Difference between Elimination and Destruction Rules\ thm conjE (* elimination *) conjunct1 (* destruction *) lemma "\x. \y. P x y \ \f. \x. P x (f x)" by meson (* try0 should be eliminated after success *) text \Split-Modifier\ lemma "sorted (case g x of [] \ [5] | y # ys \ ys @ zs @ [y])" apply (simp only: split: list.splits) oops text \Modifiers-Demo: Mergesort\ fun split_list :: "'a list \ 'a list \ 'a list" where "split_list (x # y # xs) = (case split_list xs of (one,two) \ (x # one, y # two))" | "split_list xs = (xs,[])" fun merge :: "'a :: linorder list \ 'a list \ 'a list" where "merge [] ys = ys" | "merge xs [] = xs" | "merge (x # xs) (y # ys) = (if x \ y then x # merge xs (y # ys) else y # merge (x # xs) ys)" function (sequential) msort :: "'a :: linorder list \ 'a list" where "msort [] = []" | "msort [x] = [x]" | "msort xs = (case split_list xs of (one,two) \ merge (msort one) (msort two))" by pat_completeness auto lemma split_len: "split_list xs = (one,two) \ max (length one) (length two) \ length xs" by (induction xs arbitrary: one two rule: split_list.induct) (auto split: prod.splits) termination by (relation "measure length") (auto dest: split_len split: prod.splits) lemma set_merge[simp]: "set (merge xs ys) = set xs \ set ys" by (induction xs ys rule: merge.induct) auto lemma merge: "sorted xs \ sorted ys \ sorted (merge xs ys)" by (induction xs ys rule: merge.induct) auto lemma merge_sort: "sorted (msort xs)" by (induction xs rule: msort.induct) (auto split: prod.splits intro: merge) text \Sequential composition\ lemma "\ x :: nat. x < 30 \ (\ y z. y + x \ z \ odd y \ odd z)" apply (intro allI impI) thm exI apply (rule exI[of _ 5]) apply (rule exI[of _ 35]) by auto lemma "\ x :: nat. x < 30 \ (\ y z. y + x \ z \ odd y \ odd z)" by (intro allI impI, rule exI[of _ 5], intro exI[of _ 35], auto) lemma "True \ True" apply (rule conjI; (rule TrueI; rule TrueI)) oops lemma "True \ True" apply (rule conjI, rule TrueI, rule TrueI) oops lemma "True \ True" apply (rule conjI, rule TrueI) oops lemma "True \ True" apply (rule conjI; rule TrueI) oops section \Sledgehammer\ lemma sqrt_2_irrational: "\ (\ q :: rat. q^2 = 2)" proof assume "\ q :: rat. q^2 = 2" then obtain q :: rat where "q^2 = 2" by blast obtain m n where "q = of_int m / of_int n" "coprime m n" by (metis Fract_of_int_quotient Rat_cases) then have "of_int m ^ 2 = (2::rat) * of_int n ^ 2" by (metis \q\<^sup>2 = 2\ divide_eq_eq_numeral(1) power_divide zero_neq_numeral) then have "2 dvd m" by (metis (mono_tags, lifting) even_mult_iff even_numeral of_int_eq_iff of_int_mult of_int_numeral power2_eq_square) then obtain r where "m = 2*r" by blast then have "(2 :: rat) * of_int r ^ 2 = of_int n ^ 2" using \(rat_of_int m)\<^sup>2 = 2 * (rat_of_int n)\<^sup>2\ by auto then have "2 dvd n" by (metis even_mult_iff even_numeral of_int_eq_of_int_power_cancel_iff of_int_mult of_int_numeral power2_eq_square) then show False using \coprime m n\ \even m\ by fastforce qed end