# HG changeset patch # User haftmann # Date 1616410191 0 # Node ID ee1c4962671cd236648a64eff7be90856b6531f7 # Parent 1e5c1f8a35cdd79425443699d2909c6d694caed6 more lemmas diff -r 1e5c1f8a35cd -r ee1c4962671c NEWS --- a/NEWS Mon Mar 22 00:07:55 2021 +0100 +++ b/NEWS Mon Mar 22 10:49:51 2021 +0000 @@ -65,8 +65,8 @@ specific "List_Permutation". Note that most notions from that theory are already present in theory "Permutations". INCOMPATIBILITY. -* Lemma "permutes_induct" has been given named premises. -INCOMPATIBILITY. +* Lemma "permutes_induct" has been given stronger +hypotheses and named premises. INCOMPATIBILITY. * Theorems "antisym" and "eq_iff" in class "order" have been renamed to "order.antisym" and "order.eq_iff", to coexist locally with "antisym" @@ -75,6 +75,9 @@ "order" are replaced or augmented by interpretations of locale "ordering". +* Theorem "swap_def" now is always qualified as "Fun.swap_def". Minor +INCOMPATIBILITY; note that for most applications less elementary lemmas +exists. *** ML *** diff -r 1e5c1f8a35cd -r ee1c4962671c src/HOL/Analysis/Brouwer_Fixpoint.thy --- a/src/HOL/Analysis/Brouwer_Fixpoint.thy Mon Mar 22 00:07:55 2021 +0100 +++ b/src/HOL/Analysis/Brouwer_Fixpoint.thy Mon Mar 22 10:49:51 2021 +0000 @@ -234,11 +234,6 @@ by auto qed -lemma swap_image: - "Fun.swap i j f ` A = (if i \ A then (if j \ A then f ` A else f ` ((A - {i}) \ {j})) - else (if j \ A then f ` ((A - {j}) \ {i}) else f ` A))" - by (auto simp: swap_def cong: image_cong_simp) - lemmas swap_apply1 = swap_apply(1) lemmas swap_apply2 = swap_apply(2) @@ -2598,5 +2593,4 @@ using derf has_derivative_continuous by blast qed (use assms in auto) - end diff -r 1e5c1f8a35cd -r ee1c4962671c src/HOL/Analysis/Cartesian_Space.thy --- a/src/HOL/Analysis/Cartesian_Space.thy Mon Mar 22 00:07:55 2021 +0100 +++ b/src/HOL/Analysis/Cartesian_Space.thy Mon Mar 22 10:49:51 2021 +0000 @@ -1295,7 +1295,7 @@ case False have *: "A $ i $ Fun.swap k l id j = 0" if "j \ k" "j \ K" "i \ j" for i j using False l insert.prems that - by (auto simp: swap_def insert split: if_split_asm) + by (auto simp: swap_id_eq insert split: if_split_asm) have "P (\ i j. (\ i j. A $ i $ Fun.swap k l id j) $ i $ Fun.swap k l id j)" by (rule swap_cols [OF nonzero_hyp False]) (auto simp: l *) moreover @@ -1418,7 +1418,7 @@ have eq: "(\j\UNIV. if i = Fun.swap m n id j then x $ j else 0) = (\j\UNIV. if j = Fun.swap m n id i then x $ j else 0)" for i and x :: "real^'n" - unfolding swap_def by (rule sum.cong) auto + by (rule sum.cong) (auto simp add: swap_id_eq) have "(\x::real^'n. \ i. x $ Fun.swap m n id i) = ((*v) (\ i j. if i = Fun.swap m n id j then 1 else 0))" by (auto simp: mat_def matrix_vector_mult_def eq if_distrib [of "\x. x * y" for y] cong: if_cong) with swap [OF \m \ n\] show "P ((*v) (\ i j. mat 1 $ i $ Fun.swap m n id j))" diff -r 1e5c1f8a35cd -r ee1c4962671c src/HOL/Analysis/Infinite_Products.thy --- a/src/HOL/Analysis/Infinite_Products.thy Mon Mar 22 00:07:55 2021 +0100 +++ b/src/HOL/Analysis/Infinite_Products.thy Mon Mar 22 10:49:51 2021 +0000 @@ -686,8 +686,10 @@ show ?thesis proof assume cf: "convergent_prod f" + with f have "\ (\n. prod f {..n}) \ 0" + by simp then have "\ (\n. prod g {..n}) \ 0" - using tendsto_mult_left * convergent_prod_to_zero_iff f filterlim_cong by fastforce + using * \C \ 0\ filterlim_cong by fastforce then show "convergent_prod g" by (metis convergent_mult_const_iff \C \ 0\ cong cf convergent_LIMSEQ_iff convergent_prod_iff_convergent convergent_prod_imp_convergent g) next diff -r 1e5c1f8a35cd -r ee1c4962671c src/HOL/Fun.thy --- a/src/HOL/Fun.thy Mon Mar 22 00:07:55 2021 +0100 +++ b/src/HOL/Fun.thy Mon Mar 22 10:49:51 2021 +0000 @@ -500,6 +500,23 @@ by (rule bijI) qed +lemma bij_betw_partition: + \bij_betw f A B\ + if \bij_betw f (A \ C) (B \ D)\ \bij_betw f C D\ \A \ C = {}\ \B \ D = {}\ +proof - + from that have \inj_on f (A \ C)\ \inj_on f C\ \f ` (A \ C) = B \ D\ \f ` C = D\ + by (simp_all add: bij_betw_def) + then have \inj_on f A\ and \f ` (A - C) \ f ` (C - A) = {}\ + by (simp_all add: inj_on_Un) + with \A \ C = {}\ have \f ` A \ f ` C = {}\ + by auto + with \f ` (A \ C) = B \ D\ \f ` C = D\ \B \ D = {}\ + have \f ` A = B\ + by blast + with \inj_on f A\ show ?thesis + by (simp add: bij_betw_def) +qed + lemma surj_image_vimage_eq: "surj f \ f ` (f -` A) = A" by simp @@ -823,8 +840,11 @@ subsection \\swap\\ -definition swap :: "'a \ 'a \ ('a \ 'b) \ ('a \ 'b)" - where "swap a b f = f (a := f b, b:= f a)" +context +begin + +qualified definition swap :: \'a \ 'a \ ('a \ 'b) \ ('a \ 'b)\ + where \swap a b f = f (a := f b, b:= f a)\ lemma swap_apply [simp]: "swap a b f a = f b" @@ -891,19 +911,29 @@ lemma bij_swap_iff [simp]: "bij (swap a b f) \ bij f" by simp +lemma swap_image: + \swap i j f ` A = f ` (A - {i, j} + \ (if i \ A then {j} else {}) \ (if j \ A then {i} else {}))\ + by (auto simp add: swap_def) + + subsection \Transpositions\ -lemma swap_id_idempotent [simp]: "Fun.swap a b id \ Fun.swap a b id = id" - by (rule ext) (auto simp add: Fun.swap_def) +lemma swap_id_eq: "swap a b id x = (if x = a then b else if x = b then a else x)" + by (simp add: swap_def) -lemma swap_id_eq: "Fun.swap a b id x = (if x = a then b else if x = b then a else x)" - by (simp add: Fun.swap_def) +lemma swap_unfold: + \swap a b p = p \ swap a b id\ + by (simp add: fun_eq_iff swap_def) + +lemma swap_id_idempotent [simp]: "swap a b id \ swap a b id = id" + by (simp flip: swap_unfold) lemma bij_swap_compose_bij: - \bij (Fun.swap a b id \ p)\ if \bij p\ + \bij (swap a b id \ p)\ if \bij p\ using that by (rule bij_comp) simp -hide_const (open) swap +end subsection \Inversion of injective functions\ diff -r 1e5c1f8a35cd -r ee1c4962671c src/HOL/Library/Multiset.thy --- a/src/HOL/Library/Multiset.thy Mon Mar 22 00:07:55 2021 +0100 +++ b/src/HOL/Library/Multiset.thy Mon Mar 22 10:49:51 2021 +0000 @@ -2027,6 +2027,10 @@ by (cases "x \# A") simp_all qed +lemma mset_set_upto_eq_mset_upto: + \mset_set {.. + by (induction n) (auto simp: ac_simps lessThan_Suc) + context linorder begin diff -r 1e5c1f8a35cd -r ee1c4962671c src/HOL/Library/Permutations.thy --- a/src/HOL/Library/Permutations.thy Mon Mar 22 00:07:55 2021 +0100 +++ b/src/HOL/Library/Permutations.thy Mon Mar 22 10:49:51 2021 +0000 @@ -8,90 +8,206 @@ imports Multiset Disjoint_Sets begin +subsection \Auxiliary\ + +abbreviation (input) fixpoints :: \('a \ 'a) \ 'a set\ + where \fixpoints f \ {x. f x = x}\ + +lemma inj_on_fixpoints: + \inj_on f (fixpoints f)\ + by (rule inj_onI) simp + +lemma bij_betw_fixpoints: + \bij_betw f (fixpoints f) (fixpoints f)\ + using inj_on_fixpoints by (auto simp add: bij_betw_def) + + subsection \Basic definition and consequences\ -definition permutes (infixr "permutes" 41) - where "(p permutes S) \ (\x. x \ S \ p x = x) \ (\y. \!x. p x = y)" +definition permutes :: \('a \ 'a) \ 'a set \ bool\ (infixr \permutes\ 41) + where \p permutes S \ (\x. x \ S \ p x = x) \ (\y. \!x. p x = y)\ -lemma permutes_in_image: "p permutes S \ p x \ S \ x \ S" - unfolding permutes_def by metis +lemma bij_imp_permutes: + \p permutes S\ if \bij_betw p S S\ and stable: \\x. x \ S \ p x = x\ +proof - + note \bij_betw p S S\ + moreover have \bij_betw p (- S) (- S)\ + by (auto simp add: stable intro!: bij_betw_imageI inj_onI) + ultimately have \bij_betw p (S \ - S) (S \ - S)\ + by (rule bij_betw_combine) simp + then have \\!x. p x = y\ for y + by (simp add: bij_iff) + with stable show ?thesis + by (simp add: permutes_def) +qed -lemma permutes_not_in: "f permutes S \ x \ S \ f x = x" - by (auto simp: permutes_def) +context + fixes p :: \'a \ 'a\ and S :: \'a set\ + assumes perm: \p permutes S\ +begin + +lemma permutes_inj: + \inj p\ + using perm by (auto simp: permutes_def inj_on_def) -lemma permutes_image: "p permutes S \ p ` S = S" - unfolding permutes_def - apply (rule set_eqI) - apply (simp add: image_iff) - apply metis - done +lemma permutes_image: + \p ` S = S\ +proof (rule set_eqI) + fix x + show \x \ p ` S \ x \ S\ + proof + assume \x \ p ` S\ + then obtain y where \y \ S\ \p y = x\ + by blast + with perm show \x \ S\ + by (cases \y = x\) (auto simp add: permutes_def) + next + assume \x \ S\ + with perm obtain y where \y \ S\ \p y = x\ + by (metis permutes_def) + then show \x \ p ` S\ + by blast + qed +qed + +lemma permutes_not_in: + \x \ S \ p x = x\ + using perm by (auto simp: permutes_def) + +lemma permutes_image_complement: + \p ` (- S) = - S\ + by (auto simp add: permutes_not_in) -lemma permutes_inj: "p permutes S \ inj p" - unfolding permutes_def inj_def by blast +lemma permutes_in_image: + \p x \ S \ x \ S\ + using permutes_image permutes_inj by (auto dest: inj_image_mem_iff) + +lemma permutes_surj: + \surj p\ +proof - + have \p ` (S \ - S) = p ` S \ p ` (- S)\ + by (rule image_Un) + then show ?thesis + by (simp add: permutes_image permutes_image_complement) +qed -lemma permutes_inj_on: "f permutes S \ inj_on f A" - by (auto simp: permutes_def inj_on_def) +lemma permutes_inv_o: + shows "p \ inv p = id" + and "inv p \ p = id" + using permutes_inj permutes_surj + unfolding inj_iff [symmetric] surj_iff [symmetric] by auto + +lemma permutes_inverses: + shows "p (inv p x) = x" + and "inv p (p x) = x" + using permutes_inv_o [unfolded fun_eq_iff o_def] by auto -lemma permutes_surj: "p permutes s \ surj p" - unfolding permutes_def surj_def by metis +lemma permutes_inv_eq: + \inv p y = x \ p x = y\ + by (auto simp add: permutes_inverses) -lemma permutes_bij: "p permutes s \ bij p" +lemma permutes_inj_on: + \inj_on p A\ + by (rule inj_on_subset [of _ UNIV]) (auto intro: permutes_inj) + +lemma permutes_bij: + \bij p\ unfolding bij_def by (metis permutes_inj permutes_surj) -lemma permutes_imp_bij: "p permutes S \ bij_betw p S S" - by (metis UNIV_I bij_betw_subset permutes_bij permutes_image subsetI) - -lemma bij_imp_permutes: "bij_betw p S S \ (\x. x \ S \ p x = x) \ p permutes S" - unfolding permutes_def bij_betw_def inj_on_def - by auto (metis image_iff)+ +lemma permutes_imp_bij: + \bij_betw p S S\ + by (simp add: bij_betw_def permutes_image permutes_inj_on) -lemma permutes_inv_o: - assumes permutes: "p permutes S" - shows "p \ inv p = id" - and "inv p \ p = id" - using permutes_inj[OF permutes] permutes_surj[OF permutes] - unfolding inj_iff[symmetric] surj_iff[symmetric] by blast+ - -lemma permutes_inverses: - fixes p :: "'a \ 'a" - assumes permutes: "p permutes S" - shows "p (inv p x) = x" - and "inv p (p x) = x" - using permutes_inv_o[OF permutes, unfolded fun_eq_iff o_def] by auto - -lemma permutes_subset: "p permutes S \ S \ T \ p permutes T" - unfolding permutes_def by blast +lemma permutes_subset: + \p permutes T\ if \S \ T\ +proof (rule bij_imp_permutes) + define R where \R = T - S\ + with that have \T = R \ S\ \R \ S = {}\ + by auto + then have \p x = x\ if \x \ R\ for x + using that by (auto intro: permutes_not_in) + then have \p ` R = R\ + by simp + with \T = R \ S\ show \bij_betw p T T\ + by (simp add: bij_betw_def permutes_inj_on image_Un permutes_image) + fix x + assume \x \ T\ + with \T = R \ S\ show \p x = x\ + by (simp add: permutes_not_in) +qed lemma permutes_imp_permutes_insert: - \p permutes insert x S\ if \p permutes S\ - using that by (rule permutes_subset) auto + \p permutes insert x S\ + by (rule permutes_subset) auto + +end + +lemma permutes_id [simp]: + \id permutes S\ + by (auto intro: bij_imp_permutes) -lemma permutes_empty[simp]: "p permutes {} \ p = id" - by (auto simp add: fun_eq_iff permutes_def) +lemma permutes_empty [simp]: + \p permutes {} \ p = id\ +proof + assume \p permutes {}\ + then show \p = id\ + by (auto simp add: fun_eq_iff permutes_not_in) +next + assume \p = id\ + then show \p permutes {}\ + by simp +qed -lemma permutes_sing[simp]: "p permutes {a} \ p = id" - by (simp add: fun_eq_iff permutes_def) metis (*somewhat slow*) +lemma permutes_sing [simp]: + \p permutes {a} \ p = id\ +proof + assume perm: \p permutes {a}\ + show \p = id\ + proof + fix x + from perm have \p ` {a} = {a}\ + by (rule permutes_image) + with perm show \p x = id x\ + by (cases \x = a\) (auto simp add: permutes_not_in) + qed +next + assume \p = id\ + then show \p permutes {a}\ + by simp +qed lemma permutes_univ: "p permutes UNIV \ (\y. \!x. p x = y)" by (simp add: permutes_def) -lemma permutes_inv_eq: "p permutes S \ inv p y = x \ p x = y" - unfolding permutes_def inv_def - apply auto - apply (erule allE[where x=y]) - apply (erule allE[where x=y]) - apply (rule someI_ex) - apply blast - apply (rule some1_equality) - apply blast - apply blast - done +lemma permutes_swap_id: "a \ S \ b \ S \ Fun.swap a b id permutes S" + by (rule bij_imp_permutes) (auto simp add: swap_id_eq) -lemma permutes_swap_id: "a \ S \ b \ S \ Fun.swap a b id permutes S" - unfolding permutes_def Fun.swap_def fun_upd_def by auto metis - -lemma permutes_superset: "p permutes S \ (\x \ S - T. p x = x) \ p permutes T" - by (simp add: Ball_def permutes_def) metis +lemma permutes_superset: + \p permutes T\ if \p permutes S\ \\x. x \ S - T \ p x = x\ +proof - + define R U where \R = T \ S\ and \U = S - T\ + then have \T = R \ (T - S)\ \S = R \ U\ \R \ U = {}\ + by auto + from that \U = S - T\ have \p ` U = U\ + by simp + from \p permutes S\ have \bij_betw p (R \ U) (R \ U)\ + by (simp add: permutes_imp_bij \S = R \ U\) + moreover have \bij_betw p U U\ + using that \U = S - T\ by (simp add: bij_betw_def permutes_inj_on) + ultimately have \bij_betw p R R\ + using \R \ U = {}\ \R \ U = {}\ by (rule bij_betw_partition) + then have \p permutes R\ + proof (rule bij_imp_permutes) + fix x + assume \x \ R\ + with \R = T \ S\ \p permutes S\ show \p x = x\ + by (cases \x \ S\) (auto simp add: permutes_not_in that(2)) + qed + then have \p permutes R \ (T - S)\ + by (rule permutes_subset) simp + with \T = R \ (T - S)\ show ?thesis + by simp +qed lemma permutes_bij_inv_into: \<^marker>\contributor \Lukas Bulwahn\\ fixes A :: "'a set" @@ -139,9 +255,6 @@ subsection \Group properties\ -lemma permutes_id: "id permutes S" - by (simp add: permutes_def) - lemma permutes_compose: "p permutes S \ q permutes S \ q \ p permutes S" unfolding permutes_def o_def by metis @@ -346,7 +459,7 @@ from pF \x \ F\ eq have "b = ?g (b, p) x" by (auto simp: permutes_def Fun.swap_def fun_upd_def fun_eq_iff) also from qF \x \ F\ eq have "\ = ?g (c, q) x" - by (auto simp: swap_def fun_upd_def fun_eq_iff) + by (auto simp: fun_upd_def fun_eq_iff) also from qF \x \ F\ have "\ = c" by (auto simp: permutes_def Fun.swap_def fun_upd_def fun_eq_iff) finally have "b = c" . @@ -388,6 +501,55 @@ using card_permutations[OF refl assms] by (auto intro: card_ge_0_finite) +subsection \Hence a sort of induction principle composing by swaps\ + +lemma permutes_induct [consumes 2, case_names id swap]: + \P p\ if \p permutes S\ \finite S\ + and id: \P id\ + and swap: \\a b p. a \ S \ b \ S \ p permutes S \ P p \ P (Fun.swap a b id \ p)\ +using \finite S\ \p permutes S\ swap proof (induction S arbitrary: p) + case empty + with id show ?case + by (simp only: permutes_empty) +next + case (insert x S p) + define q where \q = Fun.swap x (p x) id \ p\ + then have swap_q: \Fun.swap x (p x) id \ q = p\ + by (simp add: o_assoc) + from \p permutes insert x S\ have \q permutes S\ + by (simp add: q_def permutes_insert_lemma) + then have \q permutes insert x S\ + by (simp add: permutes_imp_permutes_insert) + from \q permutes S\ have \P q\ + by (auto intro: insert.IH insert.prems(2) permutes_imp_permutes_insert) + have \x \ insert x S\ + by simp + moreover from \p permutes insert x S\ have \p x \ insert x S\ + using permutes_in_image [of p \insert x S\ x] by simp + ultimately have \P (Fun.swap x (p x) id \ q)\ + using \q permutes insert x S\ \P q\ + by (rule insert.prems(2)) + then show ?case + by (simp add: swap_q) +qed + +lemma permutes_rev_induct [consumes 2, case_names id swap]: + \P p\ if \p permutes S\ \finite S\ + and id': \P id\ + and swap': \\a b p. a \ S \ b \ S \ p permutes S \ P p \ P (Fun.swap a b p)\ +using \p permutes S\ \finite S\ proof (induction rule: permutes_induct) + case id + from id' show ?case . +next + case (swap a b p) + have \P (Fun.swap (inv p a) (inv p b) p)\ + by (rule swap') (auto simp add: swap permutes_in_image permutes_inv) + also have \Fun.swap (inv p a) (inv p b) p = Fun.swap a b id \ p\ + by (rule bij_swap_comp [symmetric]) (rule permutes_bij, rule swap) + finally show ?case . +qed + + subsection \Permutations of index set for iterated operations\ lemma (in comm_monoid_set) permute: @@ -834,47 +996,39 @@ subsection \Relation to \permutes\\ -lemma permutation_permutes: "permutation p \ (\S. finite S \ p permutes S)" - unfolding permutation permutes_def bij_iff[symmetric] - apply (rule iffI, clarify) - apply (rule exI[where x="{x. p x \ x}"]) - apply simp - apply clarsimp - apply (rule_tac B="S" in finite_subset) - apply auto - done - - -subsection \Hence a sort of induction principle composing by swaps\ +lemma permutes_imp_permutation: + \permutation p\ if \finite S\ \p permutes S\ +proof - + from \p permutes S\ have \{x. p x \ x} \ S\ + by (auto dest: permutes_not_in) + then have \finite {x. p x \ x}\ + using \finite S\ by (rule finite_subset) + moreover from \p permutes S\ have \bij p\ + by (auto dest: permutes_bij) + ultimately show ?thesis + by (simp add: permutation) +qed -lemma permutes_induct [consumes 2, case_names id swap]: - \P p\ if \p permutes S\ \finite S\ - and id: \P id\ - and swap: \\a b p. a \ S \ b \ S \ permutation p \ P p \ P (Fun.swap a b id \ p)\ -using \finite S\ \p permutes S\ id swap proof (induction S arbitrary: p) - case empty - then show ?case by auto -next - case (insert x F p) - let ?r = "Fun.swap x (p x) id \ p" - let ?q = "Fun.swap x (p x) id \ ?r" - have qp: "?q = p" - by (simp add: o_assoc) - from permutes_insert_lemma[OF \p permutes insert x F\] insert have Pr: "P ?r" - by blast - from permutes_in_image[OF \p permutes insert x F\, of x] - have pxF: "p x \ insert x F" - by simp - have xF: "x \ insert x F" - by simp - have rp: "permutation ?r" - unfolding permutation_permutes - using insert.hyps(1) permutes_insert_lemma[OF \p permutes insert x F\] - by blast - from insert.prems(3)[OF xF pxF rp Pr] qp show ?case - by (simp only:) +lemma permutation_permutesE: + assumes \permutation p\ + obtains S where \finite S\ \p permutes S\ +proof - + from assms have fin: \finite {x. p x \ x}\ + by (simp add: permutation) + from assms have \bij p\ + by (simp add: permutation) + also have \UNIV = {x. p x \ x} \ {x. p x = x}\ + by auto + finally have \bij_betw p {x. p x \ x} {x. p x \ x}\ + by (rule bij_betw_partition) (auto simp add: bij_betw_fixpoints) + then have \p permutes {x. p x \ x}\ + by (auto intro: bij_imp_permutes) + with fin show thesis .. qed +lemma permutation_permutes: "permutation p \ (\S. finite S \ p permutes S)" + by (auto elim: permutation_permutesE intro: permutes_imp_permutation) + subsection \Sign of a permutation as a real number\ @@ -1084,9 +1238,6 @@ ultimately show ?thesis .. qed -lemma mset_set_upto_eq_mset_upto: "mset_set {.. \... and derive the existing property:\ lemma mset_eq_permutation: fixes xs ys :: "'a list"