# HG changeset patch # User haftmann # Date 1364068239 -3600 # Node ID f738e6dbd844e4d0f060b04492d08c9527458872 # Parent 3c886fe611b85637c4fc092144ed63627336747c fundamental revision of big operators on sets diff -r 3c886fe611b8 -r f738e6dbd844 CONTRIBUTORS --- a/CONTRIBUTORS Sat Mar 23 17:11:06 2013 +0100 +++ b/CONTRIBUTORS Sat Mar 23 20:50:39 2013 +0100 @@ -7,6 +7,9 @@ -------------------------------------- * March 2013: Florian Haftmann, TUM + Reform of "big operators" on sets. + +* March 2013: Florian Haftmann, TUM Algebraic locale hierarchy for orderings and (semi)lattices. * Feb. 2013: Florian Haftmann, TUM diff -r 3c886fe611b8 -r f738e6dbd844 NEWS --- a/NEWS Sat Mar 23 17:11:06 2013 +0100 +++ b/NEWS Sat Mar 23 20:50:39 2013 +0100 @@ -33,6 +33,28 @@ *** HOL *** +* Revised devices for recursive definitions over finite sets: + - Only one fundamental fold combinator on finite set remains: + Finite_Set.fold :: ('a => 'b => 'b) => 'b => 'a set => 'b + This is now identity on infinite sets. + - Locales (»mini packages«) for fundamental definitions with + Finite_Set.fold: folding, folding_idem. + - Locales comm_monoid_set, semilattice_order_set and + semilattice_neutr_order_set for big operators on sets. + See theory Big_Operators for canonical examples. + Note that foundational constants comm_monoid_set.F and + semilattice_set.F correspond to former combinators fold_image + and fold1 respectively. These are now gone. You may use + those foundational counstants as substitutes, but it is + preferable to interpret the above locales accordingly. + - Dropped class ab_semigroup_idem_mult (special case of lattice, + no longer needed in connection with Finite_Set.fold etc.) + - Fact renames: + card.union_inter ~> card_Un_Int [symmetric] + card.union_disjoint ~> card_Un_disjoint + +INCOMPATIBILITY. + * Locale hierarchy for abstract orderings and (semi)lattices. * Discontinued theory src/HOL/Library/Eval_Witness. diff -r 3c886fe611b8 -r f738e6dbd844 src/Doc/Main/Main_Doc.thy --- a/src/Doc/Main/Main_Doc.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/Doc/Main/Main_Doc.thy Sat Mar 23 20:50:39 2013 +0100 @@ -406,7 +406,6 @@ @{const Finite_Set.finite} & @{term_type_only Finite_Set.finite "'a set\bool"}\\ @{const Finite_Set.card} & @{term_type_only Finite_Set.card "'a set => nat"}\\ @{const Finite_Set.fold} & @{term_type_only Finite_Set.fold "('a \ 'b \ 'b) \ 'b \ 'a set \ 'b"}\\ -@{const Finite_Set.fold_image} & @{typ "('b \ 'b \ 'b) \ ('a \ 'b) \ 'b \ 'a set \ 'b"}\\ @{const Big_Operators.setsum} & @{term_type_only Big_Operators.setsum "('a => 'b) => 'a set => 'b::comm_monoid_add"}\\ @{const Big_Operators.setprod} & @{term_type_only Big_Operators.setprod "('a => 'b) => 'a set => 'b::comm_monoid_mult"}\\ \end{supertabular} diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Algebra/poly/UnivPoly2.thy --- a/src/HOL/Algebra/poly/UnivPoly2.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Algebra/poly/UnivPoly2.thy Sat Mar 23 20:50:39 2013 +0100 @@ -687,7 +687,7 @@ proof (cases "finite A") case True then show ?thesis by induct auto next - case False then show ?thesis by (simp add: setsum_def) + case False then show ?thesis by simp qed (* Instance of a more general result!!! *) diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/BNF/More_BNFs.thy --- a/src/HOL/BNF/More_BNFs.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/BNF/More_BNFs.thy Sat Mar 23 20:50:39 2013 +0100 @@ -548,16 +548,16 @@ unfolding mcard_def by auto lemma mcard_Plus[simp]: "mcard (M + N) = mcard M + mcard N" -proof- +proof - have "setsum (count M) {a. 0 < count M a + count N a} = setsum (count M) {a. a \# M}" - apply(rule setsum_mono_zero_cong_right) by auto + apply (rule setsum_mono_zero_cong_right) by auto moreover have "setsum (count N) {a. 0 < count M a + count N a} = setsum (count N) {a. a \# N}" - apply(rule setsum_mono_zero_cong_right) by auto + apply (rule setsum_mono_zero_cong_right) by auto ultimately show ?thesis - unfolding mcard_def count_union[THEN ext] comm_monoid_add_class.setsum.F_fun_f by simp + unfolding mcard_def count_union [THEN ext] by (simp add: setsum.distrib) qed lemma setsum_gt_0_iff: @@ -1207,7 +1207,7 @@ have "setsum L {aa. f aa = a \ 0 < L aa} = setsum L {aa. f aa = a \ 0 < K aa + L aa}" apply(rule setsum_mono_zero_cong_left) using C by auto ultimately show ?thesis - unfolding mmap_def unfolding comm_monoid_add_class.setsum.F_fun_f by auto + unfolding mmap_def by (auto simp add: setsum.distrib) qed lemma multiset_map_Plus[simp]: @@ -1265,10 +1265,10 @@ have "setsum (\ x. setsum (count M) (A x)) ?B = setsum (setsum (count M) o A) ?B" unfolding comp_def .. also have "... = (\x\ A ` ?B. setsum (count M) x)" - unfolding comm_monoid_add_class.setsum_reindex[OF i, symmetric] .. + unfolding setsum.reindex [OF i, symmetric] .. also have "... = setsum (count M) (\x\A ` {b. 0 < setsum (count M) (A b)}. x)" (is "_ = setsum (count M) ?J") - apply(rule comm_monoid_add_class.setsum_UN_disjoint[symmetric]) + apply(rule setsum.UNION_disjoint[symmetric]) using 0 fin unfolding A_def by (auto intro!: finite_imageI) also have "?J = {a. a \# M}" unfolding AB unfolding A_def by auto finally have "setsum (\ x. setsum (count M) (A x)) ?B = diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Big_Operators.thy --- a/src/HOL/Big_Operators.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Big_Operators.thy Sat Mar 23 20:50:39 2013 +0100 @@ -6,7 +6,7 @@ header {* Big operators and finite (non-empty) sets *} theory Big_Operators -imports Finite_Set Metis +imports Finite_Set Option Metis begin subsection {* Generic monoid operation over a set *} @@ -14,46 +14,223 @@ no_notation times (infixl "*" 70) no_notation Groups.one ("1") -locale comm_monoid_big = comm_monoid + - fixes F :: "('b \ 'a) \ 'b set \ 'a" - assumes F_eq: "F g A = (if finite A then fold_image (op *) g 1 A else 1)" +locale comm_monoid_set = comm_monoid +begin -sublocale comm_monoid_big < folding_image proof -qed (simp add: F_eq) - -context comm_monoid_big -begin +definition F :: "('b \ 'a) \ 'b set \ 'a" +where + eq_fold: "F g A = Finite_Set.fold (f \ g) 1 A" lemma infinite [simp]: "\ finite A \ F g A = 1" - by (simp add: F_eq) + by (simp add: eq_fold) + +lemma empty [simp]: + "F g {} = 1" + by (simp add: eq_fold) + +lemma insert [simp]: + assumes "finite A" and "x \ A" + shows "F g (insert x A) = g x * F g A" +proof - + interpret comp_fun_commute f + by default (simp add: fun_eq_iff left_commute) + interpret comp_fun_commute "f \ g" + by (rule comp_comp_fun_commute) + from assms show ?thesis by (simp add: eq_fold) +qed + +lemma remove: + assumes "finite A" and "x \ A" + shows "F g A = g x * F g (A - {x})" +proof - + from `x \ A` obtain B where A: "A = insert x B" and "x \ B" + by (auto dest: mk_disjoint_insert) + moreover from `finite A` this have "finite B" by simp + ultimately show ?thesis by simp +qed + +lemma insert_remove: + assumes "finite A" + shows "F g (insert x A) = g x * F g (A - {x})" + using assms by (cases "x \ A") (simp_all add: remove insert_absorb) + +lemma neutral: + assumes "\x\A. g x = 1" + shows "F g A = 1" +proof (cases "finite A") + case True from `finite A` assms show ?thesis by (induct A) simp_all +next + case False then show ?thesis by simp +qed -lemma F_cong: - assumes "A = B" "\x. x \ B \ h x = g x" - shows "F h A = F g B" -proof cases - assume "finite A" - with assms show ?thesis unfolding `A = B` by (simp cong: cong) +lemma neutral_const [simp]: + "F (\_. 1) A = 1" + by (simp add: neutral) + +lemma union_inter: + assumes "finite A" and "finite B" + shows "F g (A \ B) * F g (A \ B) = F g A * F g B" + -- {* The reversed orientation looks more natural, but LOOPS as a simprule! *} +using assms proof (induct A) + case empty then show ?case by simp next - assume "\ finite A" - then show ?thesis unfolding `A = B` by simp + case (insert x A) then show ?case + by (auto simp add: insert_absorb Int_insert_left commute [of _ "g x"] assoc left_commute) +qed + +corollary union_inter_neutral: + assumes "finite A" and "finite B" + and I0: "\x \ A \ B. g x = 1" + shows "F g (A \ B) = F g A * F g B" + using assms by (simp add: union_inter [symmetric] neutral) + +corollary union_disjoint: + assumes "finite A" and "finite B" + assumes "A \ B = {}" + shows "F g (A \ B) = F g A * F g B" + using assms by (simp add: union_inter_neutral) + +lemma subset_diff: + "B \ A \ finite A \ F g A = F g (A - B) * F g B" + by (metis Diff_partition union_disjoint Diff_disjoint finite_Un inf_commute sup_commute) + +lemma reindex: + assumes "inj_on h A" + shows "F g (h ` A) = F (g \ h) A" +proof (cases "finite A") + case True + interpret comp_fun_commute f + by default (simp add: fun_eq_iff left_commute) + interpret comp_fun_commute "f \ g" + by (rule comp_comp_fun_commute) + from assms `finite A` show ?thesis by (simp add: eq_fold fold_image comp_assoc) +next + case False with assms have "\ finite (h ` A)" by (blast dest: finite_imageD) + with False show ?thesis by simp qed -lemma strong_F_cong [cong]: - "\ A = B; !!x. x:B =simp=> g x = h x \ - \ F (%x. g x) A = F (%x. h x) B" -by (rule F_cong) (simp_all add: simp_implies_def) +lemma cong: + assumes "A = B" + assumes g_h: "\x. x \ B \ g x = h x" + shows "F g A = F h B" +proof (cases "finite A") + case True + then have "\C. C \ A \ (\x\C. g x = h x) \ F g C = F h C" + proof induct + case empty then show ?case by simp + next + case (insert x F) then show ?case apply - + apply (simp add: subset_insert_iff, clarify) + apply (subgoal_tac "finite C") + prefer 2 apply (blast dest: finite_subset [rotated]) + apply (subgoal_tac "C = insert x (C - {x})") + prefer 2 apply blast + apply (erule ssubst) + apply (simp add: Ball_def del: insert_Diff_single) + done + qed + with `A = B` g_h show ?thesis by simp +next + case False + with `A = B` show ?thesis by simp +qed -lemma F_neutral[simp]: "F (%i. 1) A = 1" -by (cases "finite A") (simp_all add: neutral) +lemma strong_cong [cong]: + assumes "A = B" "\x. x \ B =simp=> g x = h x" + shows "F (\x. g x) A = F (\x. h x) B" + by (rule cong) (insert assms, simp_all add: simp_implies_def) + +lemma UNION_disjoint: + assumes "finite I" and "\i\I. finite (A i)" + and "\i\I. \j\I. i \ j \ A i \ A j = {}" + shows "F g (UNION I A) = F (\x. F g (A x)) I" +apply (insert assms) +apply (induct rule: finite_induct) +apply simp +apply atomize +apply (subgoal_tac "\i\Fa. x \ i") + prefer 2 apply blast +apply (subgoal_tac "A x Int UNION Fa A = {}") + prefer 2 apply blast +apply (simp add: union_disjoint) +done + +lemma Union_disjoint: + assumes "\A\C. finite A" "\A\C. \B\C. A \ B \ A \ B = {}" + shows "F g (Union C) = F (F g) C" +proof cases + assume "finite C" + from UNION_disjoint [OF this assms] + show ?thesis + by (simp add: SUP_def) +qed (auto dest: finite_UnionD intro: infinite) -lemma F_neutral': "ALL a:A. g a = 1 \ F g A = 1" -by simp +lemma distrib: + "F (\x. g x * h x) A = F g A * F h A" +proof (cases "finite A") + case False then show ?thesis by simp +next + case True then show ?thesis by (rule finite_induct) (simp_all add: assoc commute left_commute) +qed + +lemma Sigma: + "finite A \ \x\A. finite (B x) \ F (\x. F (g x) (B x)) A = F (split g) (SIGMA x:A. B x)" +apply (subst Sigma_def) +apply (subst UNION_disjoint, assumption, simp) + apply blast +apply (rule cong) +apply rule +apply (simp add: fun_eq_iff) +apply (subst UNION_disjoint, simp, simp) + apply blast +apply (simp add: comp_def) +done + +lemma related: + assumes Re: "R 1 1" + and Rop: "\x1 y1 x2 y2. R x1 x2 \ R y1 y2 \ R (x1 * y1) (x2 * y2)" + and fS: "finite S" and Rfg: "\x\S. R (h x) (g x)" + shows "R (F h S) (F g S)" + using fS by (rule finite_subset_induct) (insert assms, auto) -lemma F_subset_diff: "\ B \ A; finite A \ \ F g A = F g (A - B) * F g B" -by (metis Diff_partition union_disjoint Diff_disjoint finite_Un inf_commute sup_commute) +lemma eq_general: + assumes h: "\y\S'. \!x. x \ S \ h x = y" + and f12: "\x\S. h x \ S' \ f2 (h x) = f1 x" + shows "F f1 S = F f2 S'" +proof- + from h f12 have hS: "h ` S = S'" by blast + {fix x y assume H: "x \ S" "y \ S" "h x = h y" + from f12 h H have "x = y" by auto } + hence hinj: "inj_on h S" unfolding inj_on_def Ex1_def by blast + from f12 have th: "\x. x \ S \ (f2 \ h) x = f1 x" by auto + from hS have "F f2 S' = F f2 (h ` S)" by simp + also have "\ = F (f2 o h) S" using reindex [OF hinj, of f2] . + also have "\ = F f1 S " using th cong [of _ _ "f2 o h" f1] + by blast + finally show ?thesis .. +qed -lemma F_mono_neutral_cong_left: +lemma eq_general_reverses: + assumes kh: "\y. y \ T \ k y \ S \ h (k y) = y" + and hk: "\x. x \ S \ h x \ T \ k (h x) = x \ g (h x) = j x" + shows "F j S = F g T" + (* metis solves it, but not yet available here *) + apply (rule eq_general [of T S h g j]) + apply (rule ballI) + apply (frule kh) + apply (rule ex1I[]) + apply blast + apply clarsimp + apply (drule hk) apply simp + apply (rule sym) + apply (erule conjunct1[OF conjunct2[OF hk]]) + apply (rule ballI) + apply (drule hk) + apply blast + done + +lemma mono_neutral_cong_left: assumes "finite T" and "S \ T" and "\i \ T - S. h i = 1" and "\x. x \ S \ g x = h x" shows "F g S = F h T" proof- @@ -62,25 +239,25 @@ from `finite T` `S \ T` have f: "finite S" "finite (T - S)" by (auto intro: finite_subset) show ?thesis using assms(4) - by (simp add: union_disjoint[OF f d, unfolded eq[symmetric]] F_neutral'[OF assms(3)]) + by (simp add: union_disjoint [OF f d, unfolded eq [symmetric]] neutral [OF assms(3)]) qed -lemma F_mono_neutral_cong_right: +lemma mono_neutral_cong_right: "\ finite T; S \ T; \i \ T - S. g i = 1; \x. x \ S \ g x = h x \ \ F g T = F h S" -by(auto intro!: F_mono_neutral_cong_left[symmetric]) + by (auto intro!: mono_neutral_cong_left [symmetric]) -lemma F_mono_neutral_left: +lemma mono_neutral_left: "\ finite T; S \ T; \i \ T - S. g i = 1 \ \ F g S = F g T" -by(blast intro: F_mono_neutral_cong_left) + by (blast intro: mono_neutral_cong_left) -lemma F_mono_neutral_right: +lemma mono_neutral_right: "\ finite T; S \ T; \i \ T - S. g i = 1 \ \ F g T = F g S" -by(blast intro!: F_mono_neutral_left[symmetric]) + by (blast intro!: mono_neutral_left [symmetric]) -lemma F_delta: +lemma delta: assumes fS: "finite S" - shows "F (\k. if k=a then b k else 1) S = (if a \ S then b a else 1)" + shows "F (\k. if k = a then b k else 1) S = (if a \ S then b a else 1)" proof- let ?f = "(\k. if k=a then b k else 1)" { assume a: "a \ S" @@ -94,78 +271,71 @@ have dj: "?A \ ?B = {}" by simp from fS have fAB: "finite ?A" "finite ?B" by auto have "F ?f S = F ?f ?A * F ?f ?B" - using union_disjoint[OF fAB dj, of ?f, unfolded eq[symmetric]] + using union_disjoint [OF fAB dj, of ?f, unfolded eq [symmetric]] by simp - then have ?thesis using a by simp } + then have ?thesis using a by simp } ultimately show ?thesis by blast qed -lemma F_delta': - assumes fS: "finite S" shows - "F (\k. if a = k then b k else 1) S = (if a \ S then b a else 1)" -using F_delta[OF fS, of a b, symmetric] by (auto intro: F_cong) - -lemma F_fun_f: "F (%x. g x * h x) A = (F g A * F h A)" -by (cases "finite A") (simp_all add: distrib) - - -text {* for ad-hoc proofs for @{const fold_image} *} -lemma comm_monoid_mult: "class.comm_monoid_mult (op *) 1" -proof qed (auto intro: assoc commute) - -lemma F_Un_neutral: - assumes fS: "finite S" and fT: "finite T" - and I1: "\x \ S\T. g x = 1" - shows "F g (S \ T) = F g S * F g T" -proof - - interpret comm_monoid_mult "op *" 1 by (fact comm_monoid_mult) - show ?thesis - using fS fT - apply (simp add: F_eq) - apply (rule fold_image_Un_one) - using I1 by auto -qed +lemma delta': + assumes fS: "finite S" + shows "F (\k. if a = k then b k else 1) S = (if a \ S then b a else 1)" + using delta [OF fS, of a b, symmetric] by (auto intro: cong) lemma If_cases: fixes P :: "'b \ bool" and g h :: "'b \ 'a" assumes fA: "finite A" shows "F (\x. if P x then h x else g x) A = - F h (A \ {x. P x}) * F g (A \ - {x. P x})" -proof- + F h (A \ {x. P x}) * F g (A \ - {x. P x})" +proof - have a: "A = A \ {x. P x} \ A \ -{x. P x}" "(A \ {x. P x}) \ (A \ -{x. P x}) = {}" by blast+ from fA have f: "finite (A \ {x. P x})" "finite (A \ -{x. P x})" by auto let ?g = "\x. if P x then h x else g x" - from union_disjoint[OF f a(2), of ?g] a(1) + from union_disjoint [OF f a(2), of ?g] a(1) show ?thesis - by (subst (1 2) F_cong) simp_all + by (subst (1 2) cong) simp_all qed +lemma cartesian_product: + "F (\x. F (g x) B) A = F (split g) (A <*> B)" +apply (rule sym) +apply (cases "finite A") + apply (cases "finite B") + apply (simp add: Sigma) + apply (cases "A={}", simp) + apply simp +apply (auto intro: infinite dest: finite_cartesian_productD2) +apply (cases "B = {}") apply (auto intro: infinite dest: finite_cartesian_productD1) +done + end -text {* for ad-hoc proofs for @{const fold_image} *} - -lemma (in comm_monoid_add) comm_monoid_mult: - "class.comm_monoid_mult (op +) 0" -proof qed (auto intro: add_assoc add_commute) - notation times (infixl "*" 70) notation Groups.one ("1") subsection {* Generalized summation over a set *} -definition (in comm_monoid_add) setsum :: "('b \ 'a) => 'b set => 'a" where - "setsum f A = (if finite A then fold_image (op +) f 0 A else 0)" +definition (in comm_monoid_add) setsum :: "('b \ 'a) \ 'b set \ 'a" +where + "setsum = comm_monoid_set.F plus 0" -sublocale comm_monoid_add < setsum!: comm_monoid_big "op +" 0 setsum proof -qed (fact setsum_def) +sublocale comm_monoid_add < setsum!: comm_monoid_set plus 0 +where + "setsum.F = setsum" +proof - + show "comm_monoid_set plus 0" .. + then interpret setsum!: comm_monoid_set plus 0 . + show "setsum.F = setsum" + by (simp only: setsum_def) +qed abbreviation - Setsum ("\_" [1000] 999) where - "\A == setsum (%x. x) A" + Setsum ("\_" [1000] 999) where + "\A \ setsum (%x. x) A" text{* Now: lot's of fancy syntax. First, @{term "setsum (%x. e) A"} is written @{text"\x\A. e"}. *} @@ -211,48 +381,32 @@ in [(@{const_syntax setsum}, setsum_tr')] end *} -lemma setsum_empty: - "setsum f {} = 0" - by (fact setsum.empty) +text {* TODO These are candidates for generalization *} -lemma setsum_insert: - "finite F ==> a \ F ==> setsum f (insert a F) = f a + setsum f F" - by (fact setsum.insert) - -lemma setsum_infinite: - "~ finite A ==> setsum f A = 0" - by (fact setsum.infinite) +context comm_monoid_add +begin -lemma (in comm_monoid_add) setsum_reindex: - assumes "inj_on f B" shows "setsum h (f ` B) = setsum (h \ f) B" -proof - - interpret comm_monoid_mult "op +" 0 by (fact comm_monoid_mult) - from assms show ?thesis by (auto simp add: setsum_def fold_image_reindex o_def dest!:finite_imageD) -qed - -lemma setsum_reindex_id: +lemma setsum_reindex_id: "inj_on f B ==> setsum f B = setsum id (f ` B)" -by (simp add: setsum_reindex) + by (simp add: setsum.reindex) -lemma setsum_reindex_nonzero: +lemma setsum_reindex_nonzero: assumes fS: "finite S" - and nz: "\ x y. x \ S \ y \ S \ x \ y \ f x = f y \ h (f x) = 0" - shows "setsum h (f ` S) = setsum (h o f) S" -using nz -proof(induct rule: finite_induct[OF fS]) + and nz: "\x y. x \ S \ y \ S \ x \ y \ f x = f y \ h (f x) = 0" + shows "setsum h (f ` S) = setsum (h \ f) S" +using nz proof (induct rule: finite_induct [OF fS]) case 1 thus ?case by simp next case (2 x F) { assume fxF: "f x \ f ` F" hence "\y \ F . f y = f x" by auto then obtain y where y: "y \ F" "f x = f y" by auto from "2.hyps" y have xy: "x \ y" by auto - - from "2.prems"[of x y] "2.hyps" xy y have h0: "h (f x) = 0" by simp + from "2.prems" [of x y] "2.hyps" xy y have h0: "h (f x) = 0" by simp have "setsum h (f ` insert x F) = setsum h (f ` F)" using fxF by auto also have "\ = setsum (h o f) (insert x F)" unfolding setsum.insert[OF `finite F` `x\F`] using h0 - apply (simp cong del:setsum.strong_F_cong) + apply (simp cong del: setsum.strong_cong) apply (rule "2.hyps"(3)) apply (rule_tac y="y" in "2.prems") apply simp_all @@ -264,7 +418,7 @@ using fxF "2.hyps" by simp also have "\ = setsum (h o f) (insert x F)" unfolding setsum.insert[OF `finite F` `x\F`] - apply (simp cong del:setsum.strong_F_cong) + apply (simp cong del: setsum.strong_cong) apply (rule cong [OF refl [of "op + (h (f x))"]]) apply (rule "2.hyps"(3)) apply (rule_tac y="y" in "2.prems") @@ -274,59 +428,14 @@ ultimately show ?case by blast qed -lemma setsum_cong: - "A = B ==> (!!x. x:B ==> f x = g x) ==> setsum f A = setsum g B" -by (fact setsum.F_cong) - -lemma strong_setsum_cong: - "A = B ==> (!!x. x:B =simp=> f x = g x) - ==> setsum (%x. f x) A = setsum (%x. g x) B" -by (fact setsum.strong_F_cong) - -lemma setsum_cong2: "\\x. x \ A \ f x = g x\ \ setsum f A = setsum g A" -by (auto intro: setsum_cong) +lemma setsum_cong2: + "(\x. x \ A \ f x = g x) \ setsum f A = setsum g A" + by (auto intro: setsum.cong) lemma setsum_reindex_cong: "[|inj_on f A; B = f ` A; !!a. a:A \ g a = h (f a)|] ==> setsum h B = setsum g A" -by (simp add: setsum_reindex) - -lemmas setsum_0 = setsum.F_neutral -lemmas setsum_0' = setsum.F_neutral' - -lemma setsum_Un_Int: "finite A ==> finite B ==> - setsum g (A Un B) + setsum g (A Int B) = setsum g A + setsum g B" - -- {* The reversed orientation looks more natural, but LOOPS as a simprule! *} -by (fact setsum.union_inter) - -lemma setsum_Un_disjoint: "finite A ==> finite B - ==> A Int B = {} ==> setsum g (A Un B) = setsum g A + setsum g B" -by (fact setsum.union_disjoint) - -lemma setsum_subset_diff: "\ B \ A; finite A \ \ - setsum f A = setsum f (A - B) + setsum f B" -by(fact setsum.F_subset_diff) - -lemma setsum_mono_zero_left: - "\ finite T; S \ T; \i \ T - S. f i = 0 \ \ setsum f S = setsum f T" -by(fact setsum.F_mono_neutral_left) - -lemmas setsum_mono_zero_right = setsum.F_mono_neutral_right - -lemma setsum_mono_zero_cong_left: - "\ finite T; S \ T; \i \ T - S. g i = 0; \x. x \ S \ f x = g x \ - \ setsum f S = setsum g T" -by(fact setsum.F_mono_neutral_cong_left) - -lemmas setsum_mono_zero_cong_right = setsum.F_mono_neutral_cong_right - -lemma setsum_delta: "finite S \ - setsum (\k. if k=a then b k else 0) S = (if a \ S then b a else 0)" -by(fact setsum.F_delta) - -lemma setsum_delta': "finite S \ - setsum (\k. if a = k then b k else 0) S = (if a\ S then b a else 0)" -by(fact setsum.F_delta') + by (simp add: setsum.reindex) lemma setsum_restrict_set: assumes fA: "finite A" @@ -335,70 +444,20 @@ from fA have fab: "finite (A \ B)" by auto have aba: "A \ B \ A" by blast let ?g = "\x. if x \ A\B then f x else 0" - from setsum_mono_zero_left[OF fA aba, of ?g] + from setsum.mono_neutral_left [OF fA aba, of ?g] show ?thesis by simp qed -lemma setsum_cases: - assumes fA: "finite A" - shows "setsum (\x. if P x then f x else g x) A = - setsum f (A \ {x. P x}) + setsum g (A \ - {x. P x})" - using setsum.If_cases[OF fA] . - -(*But we can't get rid of finite I. If infinite, although the rhs is 0, - the lhs need not be, since UNION I A could still be finite.*) -lemma (in comm_monoid_add) setsum_UN_disjoint: - assumes "finite I" and "ALL i:I. finite (A i)" - and "ALL i:I. ALL j:I. i \ j --> A i Int A j = {}" - shows "setsum f (UNION I A) = (\i\I. setsum f (A i))" -proof - - interpret comm_monoid_mult "op +" 0 by (fact comm_monoid_mult) - from assms show ?thesis by (simp add: setsum_def fold_image_UN_disjoint) -qed - -text{*No need to assume that @{term C} is finite. If infinite, the rhs is -directly 0, and @{term "Union C"} is also infinite, hence the lhs is also 0.*} lemma setsum_Union_disjoint: assumes "\A\C. finite A" "\A\C. \B\C. A \ B \ A Int B = {}" shows "setsum f (Union C) = setsum (setsum f) C" -proof cases - assume "finite C" - from setsum_UN_disjoint[OF this assms] - show ?thesis - by (simp add: SUP_def) -qed (force dest: finite_UnionD simp add: setsum_def) - -(*But we can't get rid of finite A. If infinite, although the lhs is 0, - the rhs need not be, since SIGMA A B could still be finite.*) -lemma (in comm_monoid_add) setsum_Sigma: - assumes "finite A" and "ALL x:A. finite (B x)" - shows "(\x\A. (\y\B x. f x y)) = (\(x,y)\(SIGMA x:A. B x). f x y)" -proof - - interpret comm_monoid_mult "op +" 0 by (fact comm_monoid_mult) - from assms show ?thesis by (simp add: setsum_def fold_image_Sigma split_def) -qed + using assms by (fact setsum.Union_disjoint) -text{*Here we can eliminate the finiteness assumptions, by cases.*} -lemma setsum_cartesian_product: - "(\x\A. (\y\B. f x y)) = (\(x,y) \ A <*> B. f x y)" -apply (cases "finite A") - apply (cases "finite B") - apply (simp add: setsum_Sigma) - apply (cases "A={}", simp) - apply (simp) -apply (auto simp add: setsum_def - dest: finite_cartesian_productD1 finite_cartesian_productD2) -done +lemma setsum_cartesian_product: + "(\x\A. (\y\B. f x y)) = (\(x,y) \ A <*> B. f x y)" + by (fact setsum.cartesian_product) -lemma setsum_addf: "setsum (%x. f x + g x) A = (setsum f A + setsum g A)" -by (fact setsum.F_fun_f) - -lemma setsum_Un_zero: - "\ finite S; finite T; \x \ S\T. f x = 0 \ \ - setsum f (S \ T) = setsum f S + setsum f T" -by(fact setsum.F_Un_neutral) - -lemma setsum_UNION_zero: +lemma setsum_UNION_zero: assumes fS: "finite S" and fSS: "\T \ S. finite T" and f0: "\T1 T2 x. T1\S \ T2\S \ T1 \ T2 \ x \ T1 \ x \ T2 \ f x = 0" shows "setsum f (\S) = setsum (\T. setsum f T) S" @@ -412,36 +471,145 @@ from fTF have fUF: "finite (\F)" by auto from "2.prems" TF fTF show ?case - by (auto simp add: H[symmetric] intro: setsum_Un_zero[OF fTF(1) fUF, of f]) + by (auto simp add: H [symmetric] intro: setsum.union_inter_neutral [OF fTF(1) fUF, of f]) +qed + +text {* Commuting outer and inner summation *} + +lemma setsum_commute: + "(\i\A. \j\B. f i j) = (\j\B. \i\A. f i j)" +proof (simp add: setsum_cartesian_product) + have "(\(x,y) \ A <*> B. f x y) = + (\(y,x) \ (%(i, j). (j, i)) ` (A \ B). f x y)" + (is "?s = _") + apply (simp add: setsum.reindex [where h = "%(i, j). (j, i)"] swap_inj_on) + apply (simp add: split_def) + done + also have "... = (\(y,x)\B \ A. f x y)" + (is "_ = ?t") + apply (simp add: swap_product) + done + finally show "?s = ?t" . +qed + +lemma setsum_Plus: + fixes A :: "'a set" and B :: "'b set" + assumes fin: "finite A" "finite B" + shows "setsum f (A <+> B) = setsum (f \ Inl) A + setsum (f \ Inr) B" +proof - + have "A <+> B = Inl ` A \ Inr ` B" by auto + moreover from fin have "finite (Inl ` A :: ('a + 'b) set)" "finite (Inr ` B :: ('a + 'b) set)" + by auto + moreover have "Inl ` A \ Inr ` B = ({} :: ('a + 'b) set)" by auto + moreover have "inj_on (Inl :: 'a \ 'a + 'b) A" "inj_on (Inr :: 'b \ 'a + 'b) B" by(auto intro: inj_onI) + ultimately show ?thesis using fin by(simp add: setsum.union_disjoint setsum.reindex) qed +end + +text {* TODO These are legacy *} + +lemma setsum_empty: + "setsum f {} = 0" + by (fact setsum.empty) + +lemma setsum_insert: + "finite F ==> a \ F ==> setsum f (insert a F) = f a + setsum f F" + by (fact setsum.insert) + +lemma setsum_infinite: + "~ finite A ==> setsum f A = 0" + by (fact setsum.infinite) + +lemma setsum_reindex: + "inj_on f B \ setsum h (f ` B) = setsum (h \ f) B" + by (fact setsum.reindex) + +lemma setsum_cong: + "A = B ==> (!!x. x:B ==> f x = g x) ==> setsum f A = setsum g B" + by (fact setsum.cong) + +lemma strong_setsum_cong: + "A = B ==> (!!x. x:B =simp=> f x = g x) + ==> setsum (%x. f x) A = setsum (%x. g x) B" + by (fact setsum.strong_cong) + +lemmas setsum_0 = setsum.neutral_const +lemmas setsum_0' = setsum.neutral + +lemma setsum_Un_Int: "finite A ==> finite B ==> + setsum g (A Un B) + setsum g (A Int B) = setsum g A + setsum g B" + -- {* The reversed orientation looks more natural, but LOOPS as a simprule! *} + by (fact setsum.union_inter) + +lemma setsum_Un_disjoint: "finite A ==> finite B + ==> A Int B = {} ==> setsum g (A Un B) = setsum g A + setsum g B" + by (fact setsum.union_disjoint) + +lemma setsum_subset_diff: "\ B \ A; finite A \ \ + setsum f A = setsum f (A - B) + setsum f B" + by (fact setsum.subset_diff) + +lemma setsum_mono_zero_left: + "\ finite T; S \ T; \i \ T - S. f i = 0 \ \ setsum f S = setsum f T" + by (fact setsum.mono_neutral_left) + +lemmas setsum_mono_zero_right = setsum.mono_neutral_right + +lemma setsum_mono_zero_cong_left: + "\ finite T; S \ T; \i \ T - S. g i = 0; \x. x \ S \ f x = g x \ + \ setsum f S = setsum g T" + by (fact setsum.mono_neutral_cong_left) + +lemmas setsum_mono_zero_cong_right = setsum.mono_neutral_cong_right + +lemma setsum_delta: "finite S \ + setsum (\k. if k=a then b k else 0) S = (if a \ S then b a else 0)" + by (fact setsum.delta) + +lemma setsum_delta': "finite S \ + setsum (\k. if a = k then b k else 0) S = (if a\ S then b a else 0)" + by (fact setsum.delta') + +lemma setsum_cases: + assumes "finite A" + shows "setsum (\x. if P x then f x else g x) A = + setsum f (A \ {x. P x}) + setsum g (A \ - {x. P x})" + using assms by (fact setsum.If_cases) + +(*But we can't get rid of finite I. If infinite, although the rhs is 0, + the lhs need not be, since UNION I A could still be finite.*) +lemma setsum_UN_disjoint: + assumes "finite I" and "ALL i:I. finite (A i)" + and "ALL i:I. ALL j:I. i \ j --> A i Int A j = {}" + shows "setsum f (UNION I A) = (\i\I. setsum f (A i))" + using assms by (fact setsum.UNION_disjoint) + +(*But we can't get rid of finite A. If infinite, although the lhs is 0, + the rhs need not be, since SIGMA A B could still be finite.*) +lemma setsum_Sigma: + assumes "finite A" and "ALL x:A. finite (B x)" + shows "(\x\A. (\y\B x. f x y)) = (\(x,y)\(SIGMA x:A. B x). f x y)" + using assms by (fact setsum.Sigma) + +lemma setsum_addf: "setsum (%x. f x + g x) A = (setsum f A + setsum g A)" + by (fact setsum.distrib) + +lemma setsum_Un_zero: + "\ finite S; finite T; \x \ S\T. f x = 0 \ \ + setsum f (S \ T) = setsum f S + setsum f T" + by (fact setsum.union_inter_neutral) + +lemma setsum_eq_general_reverses: + assumes fS: "finite S" and fT: "finite T" + and kh: "\y. y \ T \ k y \ S \ h (k y) = y" + and hk: "\x. x \ S \ h x \ T \ k (h x) = x \ g (h x) = f x" + shows "setsum f S = setsum g T" + using kh hk by (fact setsum.eq_general_reverses) + subsubsection {* Properties in more restricted classes of structures *} -lemma setsum_SucD: "setsum f A = Suc n ==> EX a:A. 0 < f a" -apply (case_tac "finite A") - prefer 2 apply (simp add: setsum_def) -apply (erule rev_mp) -apply (erule finite_induct, auto) -done - -lemma setsum_eq_0_iff [simp]: - "finite F ==> (setsum f F = 0) = (ALL a:F. f a = (0::nat))" -by (induct set: finite) auto - -lemma setsum_eq_Suc0_iff: "finite A \ - (setsum f A = Suc 0) = (EX a:A. f a = Suc 0 & (ALL b:A. a\b \ f b = 0))" -apply(erule finite_induct) -apply (auto simp add:add_is_1) -done - -lemmas setsum_eq_1_iff = setsum_eq_Suc0_iff[simplified One_nat_def[symmetric]] - -lemma setsum_Un_nat: "finite A ==> finite B ==> - (setsum f (A Un B) :: nat) = setsum f A + setsum f B - setsum f (A Int B)" - -- {* For the natural numbers, we have subtraction. *} -by (subst setsum_Un_Int [symmetric], auto simp add: algebra_simps) - lemma setsum_Un: "finite A ==> finite B ==> (setsum f (A Un B) :: 'a :: ab_group_add) = setsum f A + setsum f B - setsum f (A Int B)" @@ -456,74 +624,11 @@ with assms show ?thesis by simp (subst setsum_Un_disjoint, auto)+ qed -lemma (in comm_monoid_add) setsum_eq_general_reverses: - assumes fS: "finite S" and fT: "finite T" - and kh: "\y. y \ T \ k y \ S \ h (k y) = y" - and hk: "\x. x \ S \ h x \ T \ k (h x) = x \ g (h x) = f x" - shows "setsum f S = setsum g T" -proof - - interpret comm_monoid_mult "op +" 0 by (fact comm_monoid_mult) - show ?thesis - apply (simp add: setsum_def fS fT) - apply (rule fold_image_eq_general_inverses) - apply (rule fS) - apply (erule kh) - apply (erule hk) - done -qed - -lemma setsum_diff1_nat: "(setsum f (A - {a}) :: nat) = - (if a:A then setsum f A - f a else setsum f A)" -apply (case_tac "finite A") - prefer 2 apply (simp add: setsum_def) -apply (erule finite_induct) - apply (auto simp add: insert_Diff_if) -apply (drule_tac a = a in mk_disjoint_insert, auto) -done - lemma setsum_diff1: "finite A \ (setsum f (A - {a}) :: ('a::ab_group_add)) = (if a:A then setsum f A - f a else setsum f A)" by (erule finite_induct) (auto simp add: insert_Diff_if) -lemma setsum_diff1'[rule_format]: - "finite A \ a \ A \ (\ x \ A. f x) = f a + (\ x \ (A - {a}). f x)" -apply (erule finite_induct[where F=A and P="% A. (a \ A \ (\ x \ A. f x) = f a + (\ x \ (A - {a}). f x))"]) -apply (auto simp add: insert_Diff_if add_ac) -done - -lemma setsum_diff1_ring: assumes "finite A" "a \ A" - shows "setsum f (A - {a}) = setsum f A - (f a::'a::ring)" -unfolding setsum_diff1'[OF assms] by auto - -(* By Jeremy Siek: *) - -lemma setsum_diff_nat: -assumes "finite B" and "B \ A" -shows "(setsum f (A - B) :: nat) = (setsum f A) - (setsum f B)" -using assms -proof induct - show "setsum f (A - {}) = (setsum f A) - (setsum f {})" by simp -next - fix F x assume finF: "finite F" and xnotinF: "x \ F" - and xFinA: "insert x F \ A" - and IH: "F \ A \ setsum f (A - F) = setsum f A - setsum f F" - from xnotinF xFinA have xinAF: "x \ (A - F)" by simp - from xinAF have A: "setsum f ((A - F) - {x}) = setsum f (A - F) - f x" - by (simp add: setsum_diff1_nat) - from xFinA have "F \ A" by simp - with IH have "setsum f (A - F) = setsum f A - setsum f F" by simp - with A have B: "setsum f ((A - F) - {x}) = setsum f A - setsum f F - f x" - by simp - from xnotinF have "A - insert x F = (A - F) - {x}" by auto - with B have C: "setsum f (A - insert x F) = setsum f A - setsum f F - f x" - by simp - from finF xnotinF have "setsum f (insert x F) = setsum f F + f x" by simp - with C have "setsum f (A - insert x F) = setsum f A - setsum f (insert x F)" - by simp - thus "setsum f (A - insert x F) = setsum f A - setsum f (insert x F)" by simp -qed - lemma setsum_diff: assumes le: "finite A" "B \ A" shows "setsum f (A - B) = setsum f A - ((setsum f B)::('a::ab_group_add))" @@ -554,9 +659,7 @@ thus ?case using add_mono by fastforce qed next - case False - thus ?thesis - by (simp add: setsum_def) + case False then show ?thesis by simp qed lemma setsum_strict_mono: @@ -595,7 +698,7 @@ proof (cases "finite A") case True thus ?thesis by (induct set: finite) auto next - case False thus ?thesis by (simp add: setsum_def) + case False thus ?thesis by simp qed lemma setsum_subtractf: @@ -604,7 +707,7 @@ proof (cases "finite A") case True thus ?thesis by (simp add: diff_minus setsum_addf setsum_negf) next - case False thus ?thesis by (simp add: setsum_def) + case False thus ?thesis by simp qed lemma setsum_nonneg: @@ -620,7 +723,7 @@ with insert show ?case by simp qed next - case False thus ?thesis by (simp add: setsum_def) + case False thus ?thesis by simp qed lemma setsum_nonpos: @@ -636,7 +739,7 @@ with insert show ?case by simp qed next - case False thus ?thesis by (simp add: setsum_def) + case False thus ?thesis by simp qed lemma setsum_nonneg_leq_bound: @@ -702,7 +805,7 @@ case (insert x A) thus ?case by (simp add: distrib_left) qed next - case False thus ?thesis by (simp add: setsum_def) + case False thus ?thesis by simp qed lemma setsum_left_distrib: @@ -716,7 +819,7 @@ case (insert x A) thus ?case by (simp add: distrib_right) qed next - case False thus ?thesis by (simp add: setsum_def) + case False thus ?thesis by simp qed lemma setsum_divide_distrib: @@ -730,7 +833,7 @@ case (insert x A) thus ?case by (simp add: add_divide_distrib) qed next - case False thus ?thesis by (simp add: setsum_def) + case False thus ?thesis by simp qed lemma setsum_abs[iff]: @@ -746,7 +849,7 @@ thus ?case by (auto intro: abs_triangle_ineq order_trans) qed next - case False thus ?thesis by (simp add: setsum_def) + case False thus ?thesis by simp qed lemma setsum_abs_ge_zero[iff]: @@ -761,7 +864,7 @@ case (insert x A) thus ?case by auto qed next - case False thus ?thesis by (simp add: setsum_def) + case False thus ?thesis by simp qed lemma abs_setsum_abs[simp]: @@ -782,40 +885,18 @@ finally show ?case . qed next - case False thus ?thesis by (simp add: setsum_def) -qed - -lemma setsum_Plus: - fixes A :: "'a set" and B :: "'b set" - assumes fin: "finite A" "finite B" - shows "setsum f (A <+> B) = setsum (f \ Inl) A + setsum (f \ Inr) B" -proof - - have "A <+> B = Inl ` A \ Inr ` B" by auto - moreover from fin have "finite (Inl ` A :: ('a + 'b) set)" "finite (Inr ` B :: ('a + 'b) set)" - by auto - moreover have "Inl ` A \ Inr ` B = ({} :: ('a + 'b) set)" by auto - moreover have "inj_on (Inl :: 'a \ 'a + 'b) A" "inj_on (Inr :: 'b \ 'a + 'b) B" by(auto intro: inj_onI) - ultimately show ?thesis using fin by(simp add: setsum_Un_disjoint setsum_reindex) + case False thus ?thesis by simp qed - -text {* Commuting outer and inner summation *} +lemma setsum_diff1'[rule_format]: + "finite A \ a \ A \ (\ x \ A. f x) = f a + (\ x \ (A - {a}). f x)" +apply (erule finite_induct[where F=A and P="% A. (a \ A \ (\ x \ A. f x) = f a + (\ x \ (A - {a}). f x))"]) +apply (auto simp add: insert_Diff_if add_ac) +done -lemma setsum_commute: - "(\i\A. \j\B. f i j) = (\j\B. \i\A. f i j)" -proof (simp add: setsum_cartesian_product) - have "(\(x,y) \ A <*> B. f x y) = - (\(y,x) \ (%(i, j). (j, i)) ` (A \ B). f x y)" - (is "?s = _") - apply (simp add: setsum_reindex [where f = "%(i, j). (j, i)"] swap_inj_on) - apply (simp add: split_def) - done - also have "... = (\(y,x)\B \ A. f x y)" - (is "_ = ?t") - apply (simp add: swap_product) - done - finally show "?s = ?t" . -qed +lemma setsum_diff1_ring: assumes "finite A" "a \ A" + shows "setsum f (A - {a}) = setsum f A - (f a::'a::ring)" +unfolding setsum_diff1'[OF assms] by auto lemma setsum_product: fixes f :: "'a => ('b::semiring_0)" @@ -829,7 +910,82 @@ by(auto simp: setsum_product setsum_cartesian_product intro!: setsum_reindex_cong[symmetric]) -lemma setsum_constant [simp]: "(\x \ A. y) = of_nat(card A) * y" +lemma setsum_SucD: "setsum f A = Suc n ==> EX a:A. 0 < f a" +apply (case_tac "finite A") + prefer 2 apply simp +apply (erule rev_mp) +apply (erule finite_induct, auto) +done + +lemma setsum_eq_0_iff [simp]: + "finite F ==> (setsum f F = 0) = (ALL a:F. f a = (0::nat))" + by (induct set: finite) auto + +lemma setsum_eq_Suc0_iff: "finite A \ + setsum f A = Suc 0 \ (EX a:A. f a = Suc 0 & (ALL b:A. a\b \ f b = 0))" +apply(erule finite_induct) +apply (auto simp add:add_is_1) +done + +lemmas setsum_eq_1_iff = setsum_eq_Suc0_iff[simplified One_nat_def[symmetric]] + +lemma setsum_Un_nat: "finite A ==> finite B ==> + (setsum f (A Un B) :: nat) = setsum f A + setsum f B - setsum f (A Int B)" + -- {* For the natural numbers, we have subtraction. *} +by (subst setsum_Un_Int [symmetric], auto simp add: algebra_simps) + +lemma setsum_diff1_nat: "(setsum f (A - {a}) :: nat) = + (if a:A then setsum f A - f a else setsum f A)" +apply (case_tac "finite A") + prefer 2 apply simp +apply (erule finite_induct) + apply (auto simp add: insert_Diff_if) +apply (drule_tac a = a in mk_disjoint_insert, auto) +done + +lemma setsum_diff_nat: +assumes "finite B" and "B \ A" +shows "(setsum f (A - B) :: nat) = (setsum f A) - (setsum f B)" +using assms +proof induct + show "setsum f (A - {}) = (setsum f A) - (setsum f {})" by simp +next + fix F x assume finF: "finite F" and xnotinF: "x \ F" + and xFinA: "insert x F \ A" + and IH: "F \ A \ setsum f (A - F) = setsum f A - setsum f F" + from xnotinF xFinA have xinAF: "x \ (A - F)" by simp + from xinAF have A: "setsum f ((A - F) - {x}) = setsum f (A - F) - f x" + by (simp add: setsum_diff1_nat) + from xFinA have "F \ A" by simp + with IH have "setsum f (A - F) = setsum f A - setsum f F" by simp + with A have B: "setsum f ((A - F) - {x}) = setsum f A - setsum f F - f x" + by simp + from xnotinF have "A - insert x F = (A - F) - {x}" by auto + with B have C: "setsum f (A - insert x F) = setsum f A - setsum f F - f x" + by simp + from finF xnotinF have "setsum f (insert x F) = setsum f F + f x" by simp + with C have "setsum f (A - insert x F) = setsum f A - setsum f (insert x F)" + by simp + thus "setsum f (A - insert x F) = setsum f A - setsum f (insert x F)" by simp +qed + + +subsubsection {* Cardinality as special case of @{const setsum} *} + +lemma card_eq_setsum: + "card A = setsum (\x. 1) A" +proof - + have "plus \ (\_. Suc 0) = (\_. Suc)" + by (simp add: fun_eq_iff) + then have "Finite_Set.fold (plus \ (\_. Suc 0)) = Finite_Set.fold (\_. Suc)" + by (rule arg_cong) + then have "Finite_Set.fold (plus \ (\_. Suc 0)) 0 A = Finite_Set.fold (\_. Suc) 0 A" + by (blast intro: fun_cong) + then show ?thesis by (simp add: card.eq_fold setsum.eq_fold) +qed + +lemma setsum_constant [simp]: + "(\x \ A. y) = of_nat (card A) * y" apply (cases "finite A") apply (erule finite_induct) apply (auto simp add: algebra_simps) @@ -837,21 +993,14 @@ lemma setsum_bounded: assumes le: "\i. i\A \ f i \ (K::'a::{semiring_1, ordered_ab_semigroup_add})" - shows "setsum f A \ of_nat(card A) * K" + shows "setsum f A \ of_nat (card A) * K" proof (cases "finite A") case True thus ?thesis using le setsum_mono[where K=A and g = "%x. K"] by simp next - case False thus ?thesis by (simp add: setsum_def) + case False thus ?thesis by simp qed - -subsubsection {* Cardinality as special case of @{const setsum} *} - -lemma card_eq_setsum: - "card A = setsum (\x. 1) A" - by (simp only: card_def setsum_def) - lemma card_UN_disjoint: assumes "finite I" and "\i\I. finite (A i)" and "\i\I. \j\I. i \ j \ A i \ A j = {}" @@ -869,17 +1018,6 @@ apply (simp_all add: SUP_def id_def) done -text{*The image of a finite set can be expressed using @{term fold_image}.*} -lemma image_eq_fold_image: - "finite A ==> f ` A = fold_image (op Un) (%x. {f x}) {} A" -proof (induct rule: finite_induct) - case empty then show ?case by simp -next - interpret ab_semigroup_mult "op Un" - proof qed auto - case insert - then show ?case by simp -qed subsubsection {* Cardinality of products *} @@ -904,15 +1042,23 @@ subsection {* Generalized product over a set *} -definition (in comm_monoid_mult) setprod :: "('b \ 'a) => 'b set => 'a" where - "setprod f A = (if finite A then fold_image (op *) f 1 A else 1)" +definition (in comm_monoid_mult) setprod :: "('b \ 'a) \ 'b set \ 'a" +where + "setprod = comm_monoid_set.F times 1" -sublocale comm_monoid_mult < setprod!: comm_monoid_big "op *" 1 setprod proof -qed (fact setprod_def) +sublocale comm_monoid_mult < setprod!: comm_monoid_set times 1 +where + "setprod.F = setprod" +proof - + show "comm_monoid_set times 1" .. + then interpret setprod!: comm_monoid_set times 1 . + show "setprod.F = setprod" + by (simp only: setprod_def) +qed abbreviation - Setprod ("\_" [1000] 999) where - "\A == setprod (%x. x) A" + Setprod ("\_" [1000] 999) where + "\A \ setprod (\x. x) A" syntax "_setprod" :: "pttrn => 'a set => 'b => 'b::comm_monoid_mult" ("(3PROD _:_. _)" [0, 51, 10] 10) @@ -939,6 +1085,55 @@ "PROD x|P. t" => "CONST setprod (%x. t) {x. P}" "\x|P. t" => "CONST setprod (%x. t) {x. P}" +text {* TODO These are candidates for generalization *} + +context comm_monoid_mult +begin + +lemma setprod_reindex_id: + "inj_on f B ==> setprod f B = setprod id (f ` B)" + by (auto simp add: setprod.reindex) + +lemma setprod_reindex_cong: + "inj_on f A ==> B = f ` A ==> g = h \ f ==> setprod h B = setprod g A" + by (frule setprod.reindex, simp) + +lemma strong_setprod_reindex_cong: + assumes i: "inj_on f A" + and B: "B = f ` A" and eq: "\x. x \ A \ g x = (h \ f) x" + shows "setprod h B = setprod g A" +proof- + have "setprod h B = setprod (h o f) A" + by (simp add: B setprod.reindex [OF i, of h]) + then show ?thesis apply simp + apply (rule setprod.cong) + apply simp + by (simp add: eq) +qed + +lemma setprod_Union_disjoint: + assumes "\A\C. finite A" "\A\C. \B\C. A \ B \ A Int B = {}" + shows "setprod f (Union C) = setprod (setprod f) C" + using assms by (fact setprod.Union_disjoint) + +text{*Here we can eliminate the finiteness assumptions, by cases.*} +lemma setprod_cartesian_product: + "(\x\A. (\y\ B. f x y)) = (\(x,y)\(A <*> B). f x y)" + by (fact setprod.cartesian_product) + +lemma setprod_Un2: + assumes "finite (A \ B)" + shows "setprod f (A \ B) = setprod f (A - B) * setprod f (B - A) * setprod f (A \ B)" +proof - + have "A \ B = A - B \ (B - A) \ A \ B" + by auto + with assms show ?thesis by simp (subst setprod.union_disjoint, auto)+ +qed + +end + +text {* TODO These are legacy *} + lemma setprod_empty: "setprod f {} = 1" by (fact setprod.empty) @@ -950,126 +1145,91 @@ by (fact setprod.infinite) lemma setprod_reindex: - "inj_on f B ==> setprod h (f ` B) = setprod (h \ f) B" -by(auto simp: setprod_def fold_image_reindex o_def dest!:finite_imageD) - -lemma setprod_reindex_id: "inj_on f B ==> setprod f B = setprod id (f ` B)" -by (auto simp add: setprod_reindex) + "inj_on f B ==> setprod h (f ` B) = setprod (h \ f) B" + by (fact setprod.reindex) lemma setprod_cong: "A = B ==> (!!x. x:B ==> f x = g x) ==> setprod f A = setprod g B" -by(fact setprod.F_cong) + by (fact setprod.cong) lemma strong_setprod_cong: "A = B ==> (!!x. x:B =simp=> f x = g x) ==> setprod f A = setprod g B" -by(fact setprod.strong_F_cong) - -lemma setprod_reindex_cong: "inj_on f A ==> - B = f ` A ==> g = h \ f ==> setprod h B = setprod g A" -by (frule setprod_reindex, simp) + by (fact setprod.strong_cong) -lemma strong_setprod_reindex_cong: assumes i: "inj_on f A" - and B: "B = f ` A" and eq: "\x. x \ A \ g x = (h \ f) x" - shows "setprod h B = setprod g A" -proof- - have "setprod h B = setprod (h o f) A" - by (simp add: B setprod_reindex[OF i, of h]) - then show ?thesis apply simp - apply (rule setprod_cong) - apply simp - by (simp add: eq) -qed +lemma setprod_Un_one: + "\ finite S; finite T; \x \ S\T. f x = 1 \ + \ setprod f (S \ T) = setprod f S * setprod f T" + by (fact setprod.union_inter_neutral) -lemma setprod_Un_one: "\ finite S; finite T; \x \ S\T. f x = 1 \ - \ setprod f (S \ T) = setprod f S * setprod f T" -by(fact setprod.F_Un_neutral) - -lemmas setprod_1 = setprod.F_neutral -lemmas setprod_1' = setprod.F_neutral' - +lemmas setprod_1 = setprod.neutral_const +lemmas setprod_1' = setprod.neutral lemma setprod_Un_Int: "finite A ==> finite B ==> setprod g (A Un B) * setprod g (A Int B) = setprod g A * setprod g B" -by (fact setprod.union_inter) + by (fact setprod.union_inter) lemma setprod_Un_disjoint: "finite A ==> finite B ==> A Int B = {} ==> setprod g (A Un B) = setprod g A * setprod g B" -by (fact setprod.union_disjoint) + by (fact setprod.union_disjoint) lemma setprod_subset_diff: "\ B \ A; finite A \ \ setprod f A = setprod f (A - B) * setprod f B" -by(fact setprod.F_subset_diff) + by (fact setprod.subset_diff) lemma setprod_mono_one_left: "\ finite T; S \ T; \i \ T - S. f i = 1 \ \ setprod f S = setprod f T" -by(fact setprod.F_mono_neutral_left) + by (fact setprod.mono_neutral_left) -lemmas setprod_mono_one_right = setprod.F_mono_neutral_right +lemmas setprod_mono_one_right = setprod.mono_neutral_right lemma setprod_mono_one_cong_left: "\ finite T; S \ T; \i \ T - S. g i = 1; \x. x \ S \ f x = g x \ \ setprod f S = setprod g T" -by(fact setprod.F_mono_neutral_cong_left) + by (fact setprod.mono_neutral_cong_left) -lemmas setprod_mono_one_cong_right = setprod.F_mono_neutral_cong_right +lemmas setprod_mono_one_cong_right = setprod.mono_neutral_cong_right lemma setprod_delta: "finite S \ setprod (\k. if k=a then b k else 1) S = (if a \ S then b a else 1)" -by(fact setprod.F_delta) + by (fact setprod.delta) lemma setprod_delta': "finite S \ setprod (\k. if a = k then b k else 1) S = (if a\ S then b a else 1)" -by(fact setprod.F_delta') + by (fact setprod.delta') lemma setprod_UN_disjoint: "finite I ==> (ALL i:I. finite (A i)) ==> (ALL i:I. ALL j:I. i \ j --> A i Int A j = {}) ==> setprod f (UNION I A) = setprod (%i. setprod f (A i)) I" - by (simp add: setprod_def fold_image_UN_disjoint) - -lemma setprod_Union_disjoint: - assumes "\A\C. finite A" "\A\C. \B\C. A \ B \ A Int B = {}" - shows "setprod f (Union C) = setprod (setprod f) C" -proof cases - assume "finite C" - from setprod_UN_disjoint[OF this assms] - show ?thesis - by (simp add: SUP_def) -qed (force dest: finite_UnionD simp add: setprod_def) + by (fact setprod.UNION_disjoint) lemma setprod_Sigma: "finite A ==> ALL x:A. finite (B x) ==> (\x\A. (\y\ B x. f x y)) = (\(x,y)\(SIGMA x:A. B x). f x y)" -by(simp add:setprod_def fold_image_Sigma split_def) + by (fact setprod.Sigma) -text{*Here we can eliminate the finiteness assumptions, by cases.*} -lemma setprod_cartesian_product: - "(\x\A. (\y\ B. f x y)) = (\(x,y)\(A <*> B). f x y)" -apply (cases "finite A") - apply (cases "finite B") - apply (simp add: setprod_Sigma) - apply (cases "A={}", simp) - apply (simp) -apply (auto simp add: setprod_def - dest: finite_cartesian_productD1 finite_cartesian_productD2) -done - -lemma setprod_timesf: "setprod (%x. f x * g x) A = (setprod f A * setprod g A)" -by (fact setprod.F_fun_f) +lemma setprod_timesf: "setprod (\x. f x * g x) A = setprod f A * setprod g A" + by (fact setprod.distrib) subsubsection {* Properties in more restricted classes of structures *} -lemma setprod_eq_1_iff [simp]: - "finite F ==> (setprod f F = 1) = (ALL a:F. f a = (1::nat))" -by (induct set: finite) auto - lemma setprod_zero: "finite A ==> EX x: A. f x = (0::'a::comm_semiring_1) ==> setprod f A = 0" apply (induct set: finite, force, clarsimp) apply (erule disjE, auto) done +lemma setprod_zero_iff[simp]: "finite A ==> + (setprod f A = (0::'a::{comm_semiring_1,no_zero_divisors})) = + (EX x: A. f x = 0)" +by (erule finite_induct, auto simp:no_zero_divisors) + +lemma setprod_Un: "finite A ==> finite B ==> (ALL x: A Int B. f x \ 0) ==> + (setprod f (A Un B) :: 'a ::{field}) + = setprod f A * setprod f B / setprod f (A Int B)" +by (subst setprod_Un_Int [symmetric], auto) + lemma setprod_nonneg [rule_format]: "(ALL x: A. (0::'a::linordered_semidom) \ f x) --> 0 \ setprod f A" by (cases "finite A", induct set: finite, simp_all add: mult_nonneg_nonneg) @@ -1078,33 +1238,6 @@ --> 0 < setprod f A" by (cases "finite A", induct set: finite, simp_all add: mult_pos_pos) -lemma setprod_zero_iff[simp]: "finite A ==> - (setprod f A = (0::'a::{comm_semiring_1,no_zero_divisors})) = - (EX x: A. f x = 0)" -by (erule finite_induct, auto simp:no_zero_divisors) - -lemma setprod_pos_nat: - "finite S ==> (ALL x : S. f x > (0::nat)) ==> setprod f S > 0" -using setprod_zero_iff by(simp del:neq0_conv add:neq0_conv[symmetric]) - -lemma setprod_pos_nat_iff[simp]: - "finite S ==> (setprod f S > 0) = (ALL x : S. f x > (0::nat))" -using setprod_zero_iff by(simp del:neq0_conv add:neq0_conv[symmetric]) - -lemma setprod_Un: "finite A ==> finite B ==> (ALL x: A Int B. f x \ 0) ==> - (setprod f (A Un B) :: 'a ::{field}) - = setprod f A * setprod f B / setprod f (A Int B)" -by (subst setprod_Un_Int [symmetric], auto) - -lemma setprod_Un2: - assumes "finite (A \ B)" - shows "setprod f (A \ B) = setprod f (A - B) * setprod f (B - A) * setprod f (A \ B)" -proof - - have "A \ B = A - B \ (B - A) \ A \ B" - by auto - with assms show ?thesis by simp (subst setprod_Un_disjoint, auto)+ -qed - lemma setprod_diff1: "finite A ==> f a \ 0 ==> (setprod f (A - {a}) :: 'a :: {field}) = (if a:A then setprod f A / f a else setprod f A)" @@ -1197,7 +1330,7 @@ lemma setprod_gen_delta: assumes fS: "finite S" - shows "setprod (\k. if k=a then b k else c) S = (if a \ S then (b a ::'a::{comm_monoid_mult}) * c^ (card S - 1) else c^ card S)" + shows "setprod (\k. if k=a then b k else c) S = (if a \ S then (b a ::'a::comm_monoid_mult) * c^ (card S - 1) else c^ card S)" proof- let ?f = "(\k. if k=a then b k else c)" {assume a: "a \ S" @@ -1222,150 +1355,431 @@ ultimately show ?thesis by blast qed +lemma setprod_eq_1_iff [simp]: + "finite F ==> setprod f F = 1 \ (ALL a:F. f a = (1::nat))" + by (induct set: finite) auto -subsection {* Versions of @{const inf} and @{const sup} on non-empty sets *} +lemma setprod_pos_nat: + "finite S ==> (ALL x : S. f x > (0::nat)) ==> setprod f S > 0" +using setprod_zero_iff by(simp del:neq0_conv add:neq0_conv[symmetric]) + +lemma setprod_pos_nat_iff[simp]: + "finite S ==> (setprod f S > 0) = (ALL x : S. f x > (0::nat))" +using setprod_zero_iff by(simp del:neq0_conv add:neq0_conv[symmetric]) + + +subsection {* Generic lattice operations over a set *} no_notation times (infixl "*" 70) no_notation Groups.one ("1") -locale semilattice_big = semilattice + - fixes F :: "'a set \ 'a" - assumes F_eq: "finite A \ F A = fold1 (op *) A" + +subsubsection {* Without neutral element *} + +locale semilattice_set = semilattice +begin + +definition F :: "'a set \ 'a" +where + eq_fold': "F A = the (Finite_Set.fold (\x y. Some (case y of None \ x | Some z \ f x z)) None A)" + +lemma eq_fold: + assumes "finite A" + shows "F (insert x A) = Finite_Set.fold f x A" +proof (rule sym) + let ?f = "\x y. Some (case y of None \ x | Some z \ f x z)" + interpret comp_fun_idem f + by default (simp_all add: fun_eq_iff left_commute) + interpret comp_fun_idem "?f" + by default (simp_all add: fun_eq_iff commute left_commute split: option.split) + from assms show "Finite_Set.fold f x A = F (insert x A)" + proof induct + case empty then show ?case by (simp add: eq_fold') + next + case (insert y B) then show ?case by (simp add: insert_commute [of x] eq_fold') + qed +qed + +lemma singleton [simp]: + "F {x} = x" + by (simp add: eq_fold) + +lemma insert_not_elem: + assumes "finite A" and "x \ A" and "A \ {}" + shows "F (insert x A) = x * F A" +proof - + interpret comp_fun_idem f + by default (simp_all add: fun_eq_iff left_commute) + from `A \ {}` obtain b where "b \ A" by blast + then obtain B where *: "A = insert b B" "b \ B" by (blast dest: mk_disjoint_insert) + with `finite A` and `x \ A` + have "finite (insert x B)" and "b \ insert x B" by auto + then have "F (insert b (insert x B)) = x * F (insert b B)" + by (simp add: eq_fold) + then show ?thesis by (simp add: * insert_commute) +qed + +lemma subsumption: + assumes "finite A" and "x \ A" + shows "x * F A = F A" +proof - + from assms have "A \ {}" by auto + with `finite A` show ?thesis using `x \ A` + by (induct A rule: finite_ne_induct) (auto simp add: ac_simps insert_not_elem) +qed + +lemma insert [simp]: + assumes "finite A" and "A \ {}" + shows "F (insert x A) = x * F A" + using assms by (cases "x \ A") (simp_all add: insert_absorb subsumption insert_not_elem) + +lemma union: + assumes "finite A" "A \ {}" and "finite B" "B \ {}" + shows "F (A \ B) = F A * F B" + using assms by (induct A rule: finite_ne_induct) (simp_all add: ac_simps) + +lemma remove: + assumes "finite A" and "x \ A" + shows "F A = (if A - {x} = {} then x else x * F (A - {x}))" +proof - + from assms obtain B where "A = insert x B" and "x \ B" by (blast dest: mk_disjoint_insert) + with assms show ?thesis by simp +qed + +lemma insert_remove: + assumes "finite A" + shows "F (insert x A) = (if A - {x} = {} then x else x * F (A - {x}))" + using assms by (cases "x \ A") (simp_all add: insert_absorb remove) + +lemma subset: + assumes "finite A" "B \ {}" and "B \ A" + shows "F B * F A = F A" +proof - + from assms have "A \ {}" and "finite B" by (auto dest: finite_subset) + with assms show ?thesis by (simp add: union [symmetric] Un_absorb1) +qed + +lemma closed: + assumes "finite A" "A \ {}" and elem: "\x y. x * y \ {x, y}" + shows "F A \ A" +using `finite A` `A \ {}` proof (induct rule: finite_ne_induct) + case singleton then show ?case by simp +next + case insert with elem show ?case by force +qed + +lemma hom_commute: + assumes hom: "\x y. h (x * y) = h x * h y" + and N: "finite N" "N \ {}" + shows "h (F N) = F (h ` N)" +using N proof (induct rule: finite_ne_induct) + case singleton thus ?case by simp +next + case (insert n N) + then have "h (F (insert n N)) = h (n * F N)" by simp + also have "\ = h n * h (F N)" by (rule hom) + also have "h (F N) = F (h ` N)" by (rule insert) + also have "h n * \ = F (insert (h n) (h ` N))" + using insert by simp + also have "insert (h n) (h ` N) = h ` insert n N" by simp + finally show ?case . +qed + +end + +locale semilattice_order_set = semilattice_order + semilattice_set +begin + +lemma bounded_iff: + assumes "finite A" and "A \ {}" + shows "x \ F A \ (\a\A. x \ a)" + using assms by (induct rule: finite_ne_induct) (simp_all add: bounded_iff) + +lemma boundedI: + assumes "finite A" + assumes "A \ {}" + assumes "\a. a \ A \ x \ a" + shows "x \ F A" + using assms by (simp add: bounded_iff) + +lemma boundedE: + assumes "finite A" and "A \ {}" and "x \ F A" + obtains "\a. a \ A \ x \ a" + using assms by (simp add: bounded_iff) -sublocale semilattice_big < folding_one_idem proof -qed (simp_all add: F_eq) +lemma coboundedI: + assumes "finite A" + and "a \ A" + shows "F A \ a" +proof - + from assms have "A \ {}" by auto + from `finite A` `A \ {}` `a \ A` show ?thesis + proof (induct rule: finite_ne_induct) + case singleton thus ?case by (simp add: refl) + next + case (insert x B) + from insert have "a = x \ a \ B" by simp + then show ?case using insert by (auto intro: coboundedI2) + qed +qed + +lemma antimono: + assumes "A \ B" and "A \ {}" and "finite B" + shows "F B \ F A" +proof (cases "A = B") + case True then show ?thesis by (simp add: refl) +next + case False + have B: "B = A \ (B - A)" using `A \ B` by blast + then have "F B = F (A \ (B - A))" by simp + also have "\ = F A * F (B - A)" using False assms by (subst union) (auto intro: finite_subset) + also have "\ \ F A" by simp + finally show ?thesis . +qed + +end + + +subsubsection {* With neutral element *} + +locale semilattice_neutr_set = semilattice_neutr +begin + +definition F :: "'a set \ 'a" +where + eq_fold: "F A = Finite_Set.fold f 1 A" + +lemma infinite [simp]: + "\ finite A \ F A = 1" + by (simp add: eq_fold) + +lemma empty [simp]: + "F {} = 1" + by (simp add: eq_fold) + +lemma insert [simp]: + assumes "finite A" + shows "F (insert x A) = x * F A" +proof - + interpret comp_fun_idem f + by default (simp_all add: fun_eq_iff left_commute) + from assms show ?thesis by (simp add: eq_fold) +qed + +lemma subsumption: + assumes "finite A" and "x \ A" + shows "x * F A = F A" +proof - + from assms have "A \ {}" by auto + with `finite A` show ?thesis using `x \ A` + by (induct A rule: finite_ne_induct) (auto simp add: ac_simps) +qed + +lemma union: + assumes "finite A" and "finite B" + shows "F (A \ B) = F A * F B" + using assms by (induct A) (simp_all add: ac_simps) + +lemma remove: + assumes "finite A" and "x \ A" + shows "F A = x * F (A - {x})" +proof - + from assms obtain B where "A = insert x B" and "x \ B" by (blast dest: mk_disjoint_insert) + with assms show ?thesis by simp +qed + +lemma insert_remove: + assumes "finite A" + shows "F (insert x A) = x * F (A - {x})" + using assms by (cases "x \ A") (simp_all add: insert_absorb remove) + +lemma subset: + assumes "finite A" and "B \ A" + shows "F B * F A = F A" +proof - + from assms have "finite B" by (auto dest: finite_subset) + with assms show ?thesis by (simp add: union [symmetric] Un_absorb1) +qed + +lemma closed: + assumes "finite A" "A \ {}" and elem: "\x y. x * y \ {x, y}" + shows "F A \ A" +using `finite A` `A \ {}` proof (induct rule: finite_ne_induct) + case singleton then show ?case by simp +next + case insert with elem show ?case by force +qed + +end + +locale semilattice_order_neutr_set = semilattice_neutr_order + semilattice_neutr_set +begin + +lemma bounded_iff: + assumes "finite A" + shows "x \ F A \ (\a\A. x \ a)" + using assms by (induct A) (simp_all add: bounded_iff) + +lemma boundedI: + assumes "finite A" + assumes "\a. a \ A \ x \ a" + shows "x \ F A" + using assms by (simp add: bounded_iff) + +lemma boundedE: + assumes "finite A" and "x \ F A" + obtains "\a. a \ A \ x \ a" + using assms by (simp add: bounded_iff) + +lemma coboundedI: + assumes "finite A" + and "a \ A" + shows "F A \ a" +proof - + from assms have "A \ {}" by auto + from `finite A` `A \ {}` `a \ A` show ?thesis + proof (induct rule: finite_ne_induct) + case singleton thus ?case by (simp add: refl) + next + case (insert x B) + from insert have "a = x \ a \ B" by simp + then show ?case using insert by (auto intro: coboundedI2) + qed +qed + +lemma antimono: + assumes "A \ B" and "finite B" + shows "F B \ F A" +proof (cases "A = B") + case True then show ?thesis by (simp add: refl) +next + case False + have B: "B = A \ (B - A)" using `A \ B` by blast + then have "F B = F (A \ (B - A))" by simp + also have "\ = F A * F (B - A)" using False assms by (subst union) (auto intro: finite_subset) + also have "\ \ F A" by simp + finally show ?thesis . +qed + +end notation times (infixl "*" 70) notation Groups.one ("1") -context lattice -begin -definition Inf_fin :: "'a set \ 'a" ("\\<^bsub>fin\<^esub>_" [900] 900) where - "Inf_fin = fold1 inf" - -definition Sup_fin :: "'a set \ 'a" ("\\<^bsub>fin\<^esub>_" [900] 900) where - "Sup_fin = fold1 sup" - -end +subsection {* Lattice operations on finite sets *} -sublocale lattice < Inf_fin!: semilattice_big inf Inf_fin proof -qed (simp add: Inf_fin_def) - -sublocale lattice < Sup_fin!: semilattice_big sup Sup_fin proof -qed (simp add: Sup_fin_def) +text {* + For historic reasons, there is the sublocale dependency from @{class distrib_lattice} + to @{class linorder}. This is badly designed: both should depend on a common abstract + distributive lattice rather than having this non-subclass dependecy between two + classes. But for the moment we have to live with it. This forces us to setup + this sublocale dependency simultaneously with the lattice operations on finite + sets, to avoid garbage. +*} -context semilattice_inf -begin +definition (in semilattice_inf) Inf_fin :: "'a set \ 'a" ("\\<^bsub>fin\<^esub>_" [900] 900) +where + "Inf_fin = semilattice_set.F inf" -lemma ab_semigroup_idem_mult_inf: - "class.ab_semigroup_idem_mult inf" -proof qed (rule inf_assoc inf_commute inf_idem)+ +definition (in semilattice_sup) Sup_fin :: "'a set \ 'a" ("\\<^bsub>fin\<^esub>_" [900] 900) +where + "Sup_fin = semilattice_set.F sup" -lemma fold_inf_insert[simp]: "finite A \ Finite_Set.fold inf b (insert a A) = inf a (Finite_Set.fold inf b A)" -by(rule comp_fun_idem.fold_insert_idem[OF ab_semigroup_idem_mult.comp_fun_idem[OF ab_semigroup_idem_mult_inf]]) +definition (in linorder) Min :: "'a set \ 'a" +where + "Min = semilattice_set.F min" -lemma inf_le_fold_inf: "finite A \ ALL a:A. b \ a \ inf b c \ Finite_Set.fold inf c A" -by (induct pred: finite) (auto intro: le_infI1) +definition (in linorder) Max :: "'a set \ 'a" +where + "Max = semilattice_set.F max" + +text {* An aside: @{const min}/@{const max} on linear orders as special case of @{const inf}/@{const sup} *} -lemma fold_inf_le_inf: "finite A \ a \ A \ Finite_Set.fold inf b A \ inf a b" -proof(induct arbitrary: a pred:finite) - case empty thus ?case by simp -next - case (insert x A) - show ?case - proof cases - assume "A = {}" thus ?thesis using insert by simp - next - assume "A \ {}" thus ?thesis using insert by (auto intro: le_infI2) - qed -qed - -lemma below_fold1_iff: - assumes "finite A" "A \ {}" - shows "x \ fold1 inf A \ (\a\A. x \ a)" +sublocale linorder < min_max!: distrib_lattice min less_eq less max +where + "semilattice_inf.Inf_fin min = Min" + and "semilattice_sup.Sup_fin max = Max" proof - - interpret ab_semigroup_idem_mult inf - by (rule ab_semigroup_idem_mult_inf) - show ?thesis using assms by (induct rule: finite_ne_induct) simp_all + show "class.distrib_lattice min less_eq less max" + proof + fix x y z + show "max x (min y z) = min (max x y) (max x z)" + by (auto simp add: min_def max_def) + qed (auto simp add: min_def max_def not_le less_imp_le) + then interpret min_max!: distrib_lattice min less_eq less max . + show "semilattice_inf.Inf_fin min = Min" + by (simp only: min_max.Inf_fin_def Min_def) + show "semilattice_sup.Sup_fin max = Max" + by (simp only: min_max.Sup_fin_def Max_def) qed -lemma fold1_belowI: - assumes "finite A" - and "a \ A" - shows "fold1 inf A \ a" +lemma inf_min: "inf = (min \ 'a\{semilattice_inf, linorder} \ 'a \ 'a)" + by (rule ext)+ (auto intro: antisym) + +lemma sup_max: "sup = (max \ 'a\{semilattice_sup, linorder} \ 'a \ 'a)" + by (rule ext)+ (auto intro: antisym) + +lemmas le_maxI1 = min_max.sup_ge1 +lemmas le_maxI2 = min_max.sup_ge2 + +lemmas min_ac = min_max.inf_assoc min_max.inf_commute + min_max.inf.left_commute + +lemmas max_ac = min_max.sup_assoc min_max.sup_commute + min_max.sup.left_commute + + +text {* Lattice operations proper *} + +sublocale semilattice_inf < Inf_fin!: semilattice_order_set inf less_eq less +where + "Inf_fin.F = Inf_fin" proof - - from assms have "A \ {}" by auto - from `finite A` `A \ {}` `a \ A` show ?thesis - proof (induct rule: finite_ne_induct) - case singleton thus ?case by simp - next - interpret ab_semigroup_idem_mult inf - by (rule ab_semigroup_idem_mult_inf) - case (insert x F) - from insert(5) have "a = x \ a \ F" by simp - thus ?case - proof - assume "a = x" thus ?thesis using insert - by (simp add: mult_ac) - next - assume "a \ F" - hence bel: "fold1 inf F \ a" by (rule insert) - have "inf (fold1 inf (insert x F)) a = inf x (inf (fold1 inf F) a)" - using insert by (simp add: mult_ac) - also have "inf (fold1 inf F) a = fold1 inf F" - using bel by (auto intro: antisym) - also have "inf x \ = fold1 inf (insert x F)" - using insert by (simp add: mult_ac) - finally have aux: "inf (fold1 inf (insert x F)) a = fold1 inf (insert x F)" . - moreover have "inf (fold1 inf (insert x F)) a \ a" by simp - ultimately show ?thesis by simp - qed - qed + show "semilattice_order_set inf less_eq less" .. + then interpret Inf_fin!: semilattice_order_set inf less_eq less. + show "Inf_fin.F = Inf_fin" + by (fact Inf_fin_def [symmetric]) qed -end - -context semilattice_sup -begin - -lemma ab_semigroup_idem_mult_sup: "class.ab_semigroup_idem_mult sup" -by (rule semilattice_inf.ab_semigroup_idem_mult_inf)(rule dual_semilattice) +sublocale semilattice_sup < Sup_fin!: semilattice_order_set sup greater_eq greater +where + "Sup_fin.F = Sup_fin" +proof - + show "semilattice_order_set sup greater_eq greater" .. + then interpret Sup_fin!: semilattice_order_set sup greater_eq greater . + show "Sup_fin.F = Sup_fin" + by (fact Sup_fin_def [symmetric]) +qed -lemma fold_sup_insert[simp]: "finite A \ Finite_Set.fold sup b (insert a A) = sup a (Finite_Set.fold sup b A)" -by(rule semilattice_inf.fold_inf_insert)(rule dual_semilattice) + +subsection {* Infimum and Supremum over non-empty sets *} -lemma fold_sup_le_sup: "finite A \ ALL a:A. a \ b \ Finite_Set.fold sup c A \ sup b c" -by(rule semilattice_inf.inf_le_fold_inf)(rule dual_semilattice) - -lemma sup_le_fold_sup: "finite A \ a \ A \ sup a b \ Finite_Set.fold sup b A" -by(rule semilattice_inf.fold_inf_le_inf)(rule dual_semilattice) - -end +text {* + After this non-regular bootstrap, things continue canonically. +*} context lattice begin lemma Inf_le_Sup [simp]: "\ finite A; A \ {} \ \ \\<^bsub>fin\<^esub>A \ \\<^bsub>fin\<^esub>A" -apply(unfold Sup_fin_def Inf_fin_def) apply(subgoal_tac "EX a. a:A") prefer 2 apply blast apply(erule exE) apply(rule order_trans) -apply(erule (1) fold1_belowI) -apply(erule (1) semilattice_inf.fold1_belowI [OF dual_semilattice]) +apply(erule (1) Inf_fin.coboundedI) +apply(erule (1) Sup_fin.coboundedI) done lemma sup_Inf_absorb [simp]: "finite A \ a \ A \ sup a (\\<^bsub>fin\<^esub>A) = a" apply(subst sup_commute) -apply(simp add: Inf_fin_def sup_absorb2 fold1_belowI) +apply(simp add: sup_absorb2 Inf_fin.coboundedI) done lemma inf_Sup_absorb [simp]: "finite A \ a \ A \ inf a (\\<^bsub>fin\<^esub>A) = a" -by (simp add: Sup_fin_def inf_absorb1 - semilattice_inf.fold1_belowI [OF dual_semilattice]) +by (simp add: inf_absorb1 Sup_fin.coboundedI) end @@ -1376,27 +1790,19 @@ assumes "finite A" and "A \ {}" shows "sup x (\\<^bsub>fin\<^esub>A) = \\<^bsub>fin\<^esub>{sup x a|a. a \ A}" -proof - - interpret ab_semigroup_idem_mult inf - by (rule ab_semigroup_idem_mult_inf) - from assms show ?thesis - by (simp add: Inf_fin_def image_def - hom_fold1_commute [where h="sup x", OF sup_inf_distrib1]) - (rule arg_cong [where f="fold1 inf"], blast) -qed +using assms by (simp add: image_def Inf_fin.hom_commute [where h="sup x", OF sup_inf_distrib1]) + (rule arg_cong [where f="Inf_fin"], blast) lemma sup_Inf2_distrib: assumes A: "finite A" "A \ {}" and B: "finite B" "B \ {}" shows "sup (\\<^bsub>fin\<^esub>A) (\\<^bsub>fin\<^esub>B) = \\<^bsub>fin\<^esub>{sup a b|a b. a \ A \ b \ B}" using A proof (induct rule: finite_ne_induct) - case singleton thus ?case + case singleton then show ?case by (simp add: sup_Inf1_distrib [OF B]) next - interpret ab_semigroup_idem_mult inf - by (rule ab_semigroup_idem_mult_inf) case (insert x A) have finB: "finite {sup x b |b. b \ B}" - by(rule finite_surj[where f = "sup x", OF B(1)], auto) + by (rule finite_surj [where f = "sup x", OF B(1)], auto) have finAB: "finite {sup a b |a b. a \ A \ b \ B}" proof - have "{sup a b |a b. a \ A \ b \ B} = (UN a:A. UN b:B. {sup a b})" @@ -1412,7 +1818,7 @@ also have "\ = \\<^bsub>fin\<^esub>({sup x b |b. b \ B} \ {sup a b |a b. a \ A \ b \ B})" (is "_ = \\<^bsub>fin\<^esub>?M") using B insert - by (simp add: Inf_fin_def fold1_Un2 [OF finB _ finAB ne]) + by (simp add: Inf_fin.union [OF finB _ finAB ne]) also have "?M = {sup a b |a b. a \ insert x A \ b \ B}" by blast finally show ?case . @@ -1421,13 +1827,8 @@ lemma inf_Sup1_distrib: assumes "finite A" and "A \ {}" shows "inf x (\\<^bsub>fin\<^esub>A) = \\<^bsub>fin\<^esub>{inf x a|a. a \ A}" -proof - - interpret ab_semigroup_idem_mult sup - by (rule ab_semigroup_idem_mult_sup) - from assms show ?thesis - by (simp add: Sup_fin_def image_def hom_fold1_commute [where h="inf x", OF inf_sup_distrib1]) - (rule arg_cong [where f="fold1 sup"], blast) -qed +using assms by (simp add: image_def Sup_fin.hom_commute [where h="inf x", OF inf_sup_distrib1]) + (rule arg_cong [where f="Sup_fin"], blast) lemma inf_Sup2_distrib: assumes A: "finite A" "A \ {}" and B: "finite B" "B \ {}" @@ -1446,8 +1847,6 @@ thus ?thesis by(simp add: insert(1) B(1)) qed have ne: "{inf a b |a b. a \ A \ b \ B} \ {}" using insert B by blast - interpret ab_semigroup_idem_mult sup - by (rule ab_semigroup_idem_mult_sup) have "inf (\\<^bsub>fin\<^esub>(insert x A)) (\\<^bsub>fin\<^esub>B) = inf (sup x (\\<^bsub>fin\<^esub>A)) (\\<^bsub>fin\<^esub>B)" using insert by simp also have "\ = sup (inf x (\\<^bsub>fin\<^esub>B)) (inf (\\<^bsub>fin\<^esub>A) (\\<^bsub>fin\<^esub>B))" by(rule inf_sup_distrib2) @@ -1456,7 +1855,7 @@ also have "\ = \\<^bsub>fin\<^esub>({inf x b |b. b \ B} \ {inf a b |a b. a \ A \ b \ B})" (is "_ = \\<^bsub>fin\<^esub>?M") using B insert - by (simp add: Sup_fin_def fold1_Un2 [OF finB _ finAB ne]) + by (simp add: Sup_fin.union [OF finB _ finAB ne]) also have "?M = {inf a b |a b. a \ insert x A \ b \ B}" by blast finally show ?case . @@ -1471,227 +1870,84 @@ assumes "finite A" and "A \ {}" shows "\\<^bsub>fin\<^esub>A = Inf A" proof - - interpret ab_semigroup_idem_mult inf - by (rule ab_semigroup_idem_mult_inf) - from `A \ {}` obtain b B where "A = {b} \ B" by auto - moreover with `finite A` have "finite B" by simp - ultimately show ?thesis - by (simp add: Inf_fin_def fold1_eq_fold_idem inf_Inf_fold_inf [symmetric]) + from assms obtain b B where "A = insert b B" and "finite B" by auto + then show ?thesis + by (simp add: Inf_fin.eq_fold inf_Inf_fold_inf inf.commute [of b]) qed lemma Sup_fin_Sup: assumes "finite A" and "A \ {}" shows "\\<^bsub>fin\<^esub>A = Sup A" proof - - interpret ab_semigroup_idem_mult sup - by (rule ab_semigroup_idem_mult_sup) - from `A \ {}` obtain b B where "A = {b} \ B" by auto - moreover with `finite A` have "finite B" by simp - ultimately show ?thesis - by (simp add: Sup_fin_def fold1_eq_fold_idem sup_Sup_fold_sup [symmetric]) + from assms obtain b B where "A = insert b B" and "finite B" by auto + then show ?thesis + by (simp add: Sup_fin.eq_fold sup_Sup_fold_sup sup.commute [of b]) qed end -subsection {* Versions of @{const min} and @{const max} on non-empty sets *} - -definition (in linorder) Min :: "'a set \ 'a" where - "Min = fold1 min" +subsection {* Minimum and Maximum over non-empty sets *} -definition (in linorder) Max :: "'a set \ 'a" where - "Max = fold1 max" - -sublocale linorder < Min!: semilattice_big min Min proof -qed (simp add: Min_def) - -sublocale linorder < Max!: semilattice_big max Max proof -qed (simp add: Max_def) +text {* + This case is already setup by the @{text min_max} sublocale dependency from above. But note + that this yields irregular prefixes, e.g.~@{text min_max.Inf_fin.insert} instead + of @{text Max.insert}. +*} context linorder begin -lemmas Min_singleton = Min.singleton -lemmas Max_singleton = Max.singleton - -lemma Min_insert: - assumes "finite A" and "A \ {}" - shows "Min (insert x A) = min x (Min A)" - using assms by simp - -lemma Max_insert: - assumes "finite A" and "A \ {}" - shows "Max (insert x A) = max x (Max A)" - using assms by simp - -lemma Min_Un: - assumes "finite A" and "A \ {}" and "finite B" and "B \ {}" - shows "Min (A \ B) = min (Min A) (Min B)" - using assms by (rule Min.union_idem) - -lemma Max_Un: - assumes "finite A" and "A \ {}" and "finite B" and "B \ {}" - shows "Max (A \ B) = max (Max A) (Max B)" - using assms by (rule Max.union_idem) - -lemma hom_Min_commute: - assumes "\x y. h (min x y) = min (h x) (h y)" - and "finite N" and "N \ {}" - shows "h (Min N) = Min (h ` N)" - using assms by (rule Min.hom_commute) - -lemma hom_Max_commute: - assumes "\x y. h (max x y) = max (h x) (h y)" - and "finite N" and "N \ {}" - shows "h (Max N) = Max (h ` N)" - using assms by (rule Max.hom_commute) - -lemma ab_semigroup_idem_mult_min: - "class.ab_semigroup_idem_mult min" - proof qed (auto simp add: min_def) - -lemma ab_semigroup_idem_mult_max: - "class.ab_semigroup_idem_mult max" - proof qed (auto simp add: max_def) - -lemma max_lattice: - "class.semilattice_inf max (op \) (op >)" - by (fact min_max.dual_semilattice) - -lemma dual_max: - "ord.max (op \) = min" - by (auto simp add: ord.max_def min_def fun_eq_iff) - lemma dual_min: - "ord.min (op \) = max" + "ord.min greater_eq = max" by (auto simp add: ord.min_def max_def fun_eq_iff) -lemma strict_below_fold1_iff: - assumes "finite A" and "A \ {}" - shows "x < fold1 min A \ (\a\A. x < a)" +lemma dual_max: + "ord.max greater_eq = min" + by (auto simp add: ord.max_def min_def fun_eq_iff) + +lemma dual_Min: + "linorder.Min greater_eq = Max" proof - - interpret ab_semigroup_idem_mult min - by (rule ab_semigroup_idem_mult_min) - from assms show ?thesis - by (induct rule: finite_ne_induct) - (simp_all add: fold1_insert) -qed - -lemma fold1_below_iff: - assumes "finite A" and "A \ {}" - shows "fold1 min A \ x \ (\a\A. a \ x)" -proof - - interpret ab_semigroup_idem_mult min - by (rule ab_semigroup_idem_mult_min) - from assms show ?thesis - by (induct rule: finite_ne_induct) - (simp_all add: fold1_insert min_le_iff_disj) + interpret dual!: linorder greater_eq greater by (fact dual_linorder) + show ?thesis by (simp add: dual.Min_def dual_min Max_def) qed -lemma fold1_strict_below_iff: - assumes "finite A" and "A \ {}" - shows "fold1 min A < x \ (\a\A. a < x)" +lemma dual_Max: + "linorder.Max greater_eq = Min" proof - - interpret ab_semigroup_idem_mult min - by (rule ab_semigroup_idem_mult_min) - from assms show ?thesis - by (induct rule: finite_ne_induct) - (simp_all add: fold1_insert min_less_iff_disj) + interpret dual!: linorder greater_eq greater by (fact dual_linorder) + show ?thesis by (simp add: dual.Max_def dual_max Min_def) qed -lemma fold1_antimono: - assumes "A \ {}" and "A \ B" and "finite B" - shows "fold1 min B \ fold1 min A" -proof cases - assume "A = B" thus ?thesis by simp -next - interpret ab_semigroup_idem_mult min - by (rule ab_semigroup_idem_mult_min) - assume neq: "A \ B" - have B: "B = A \ (B-A)" using `A \ B` by blast - have "fold1 min B = fold1 min (A \ (B-A))" by(subst B)(rule refl) - also have "\ = min (fold1 min A) (fold1 min (B-A))" - proof - - have "finite A" by(rule finite_subset[OF `A \ B` `finite B`]) - moreover have "finite(B-A)" by(rule finite_Diff[OF `finite B`]) - moreover have "(B-A) \ {}" using assms neq by blast - moreover have "A Int (B-A) = {}" using assms by blast - ultimately show ?thesis using `A \ {}` by (rule_tac fold1_Un) - qed - also have "\ \ fold1 min A" by (simp add: min_le_iff_disj) - finally show ?thesis . -qed +lemmas Min_singleton = min_max.Inf_fin.singleton +lemmas Max_singleton = min_max.Sup_fin.singleton +lemmas Min_insert = min_max.Inf_fin.insert +lemmas Max_insert = min_max.Sup_fin.insert +lemmas Min_Un = min_max.Inf_fin.union +lemmas Max_Un = min_max.Sup_fin.union +lemmas hom_Min_commute = min_max.Inf_fin.hom_commute +lemmas hom_Max_commute = min_max.Sup_fin.hom_commute lemma Min_in [simp]: assumes "finite A" and "A \ {}" shows "Min A \ A" -proof - - interpret ab_semigroup_idem_mult min - by (rule ab_semigroup_idem_mult_min) - from assms fold1_in show ?thesis by (fastforce simp: Min_def min_def) -qed + using assms by (auto simp add: min_def min_max.Inf_fin.closed) lemma Max_in [simp]: assumes "finite A" and "A \ {}" shows "Max A \ A" -proof - - interpret ab_semigroup_idem_mult max - by (rule ab_semigroup_idem_mult_max) - from assms fold1_in [of A] show ?thesis by (fastforce simp: Max_def max_def) -qed + using assms by (auto simp add: max_def min_max.Sup_fin.closed) lemma Min_le [simp]: assumes "finite A" and "x \ A" shows "Min A \ x" - using assms by (simp add: Min_def min_max.fold1_belowI) + using assms by (fact min_max.Inf_fin.coboundedI) lemma Max_ge [simp]: assumes "finite A" and "x \ A" shows "x \ Max A" - by (simp add: Max_def semilattice_inf.fold1_belowI [OF max_lattice] assms) - -lemma Min_ge_iff [simp, no_atp]: - assumes "finite A" and "A \ {}" - shows "x \ Min A \ (\a\A. x \ a)" - using assms by (simp add: Min_def min_max.below_fold1_iff) - -lemma Max_le_iff [simp, no_atp]: - assumes "finite A" and "A \ {}" - shows "Max A \ x \ (\a\A. a \ x)" - by (simp add: Max_def semilattice_inf.below_fold1_iff [OF max_lattice] assms) - -lemma Min_gr_iff [simp, no_atp]: - assumes "finite A" and "A \ {}" - shows "x < Min A \ (\a\A. x < a)" - using assms by (simp add: Min_def strict_below_fold1_iff) - -lemma Max_less_iff [simp, no_atp]: - assumes "finite A" and "A \ {}" - shows "Max A < x \ (\a\A. a < x)" - by (simp add: Max_def linorder.dual_max [OF dual_linorder] - linorder.strict_below_fold1_iff [OF dual_linorder] assms) - -lemma Min_le_iff [no_atp]: - assumes "finite A" and "A \ {}" - shows "Min A \ x \ (\a\A. a \ x)" - using assms by (simp add: Min_def fold1_below_iff) - -lemma Max_ge_iff [no_atp]: - assumes "finite A" and "A \ {}" - shows "x \ Max A \ (\a\A. x \ a)" - by (simp add: Max_def linorder.dual_max [OF dual_linorder] - linorder.fold1_below_iff [OF dual_linorder] assms) - -lemma Min_less_iff [no_atp]: - assumes "finite A" and "A \ {}" - shows "Min A < x \ (\a\A. a < x)" - using assms by (simp add: Min_def fold1_strict_below_iff) - -lemma Max_gr_iff [no_atp]: - assumes "finite A" and "A \ {}" - shows "x < Max A \ (\a\A. x < a)" - by (simp add: Max_def linorder.dual_max [OF dual_linorder] - linorder.fold1_strict_below_iff [OF dual_linorder] assms) + using assms by (fact min_max.Sup_fin.coboundedI) lemma Min_eqI: assumes "finite A" @@ -1717,22 +1973,91 @@ from assms show "x \ Max A" by simp qed +lemma Min_ge_iff [simp, no_atp]: + assumes "finite A" and "A \ {}" + shows "x \ Min A \ (\a\A. x \ a)" + using assms by (fact min_max.Inf_fin.bounded_iff) + +lemma Max_le_iff [simp, no_atp]: + assumes "finite A" and "A \ {}" + shows "Max A \ x \ (\a\A. a \ x)" + using assms by (fact min_max.Sup_fin.bounded_iff) + +lemma Min_gr_iff [simp, no_atp]: + assumes "finite A" and "A \ {}" + shows "x < Min A \ (\a\A. x < a)" + using assms by (induct rule: finite_ne_induct) simp_all + +lemma Max_less_iff [simp, no_atp]: + assumes "finite A" and "A \ {}" + shows "Max A < x \ (\a\A. a < x)" + using assms by (induct rule: finite_ne_induct) simp_all + +lemma Min_le_iff [no_atp]: + assumes "finite A" and "A \ {}" + shows "Min A \ x \ (\a\A. a \ x)" + using assms by (induct rule: finite_ne_induct) (simp_all add: min_le_iff_disj) + +lemma Max_ge_iff [no_atp]: + assumes "finite A" and "A \ {}" + shows "x \ Max A \ (\a\A. x \ a)" + using assms by (induct rule: finite_ne_induct) (simp_all add: le_max_iff_disj) + +lemma Min_less_iff [no_atp]: + assumes "finite A" and "A \ {}" + shows "Min A < x \ (\a\A. a < x)" + using assms by (induct rule: finite_ne_induct) (simp_all add: min_less_iff_disj) + +lemma Max_gr_iff [no_atp]: + assumes "finite A" and "A \ {}" + shows "x < Max A \ (\a\A. x < a)" + using assms by (induct rule: finite_ne_induct) (simp_all add: less_max_iff_disj) + lemma Min_antimono: assumes "M \ N" and "M \ {}" and "finite N" shows "Min N \ Min M" - using assms by (simp add: Min_def fold1_antimono) + using assms by (fact min_max.Inf_fin.antimono) lemma Max_mono: assumes "M \ N" and "M \ {}" and "finite N" shows "Max M \ Max N" - by (simp add: Max_def linorder.dual_max [OF dual_linorder] - linorder.fold1_antimono [OF dual_linorder] assms) + using assms by (fact min_max.Sup_fin.antimono) + +lemma mono_Min_commute: + assumes "mono f" + assumes "finite A" and "A \ {}" + shows "f (Min A) = Min (f ` A)" +proof (rule linorder_class.Min_eqI [symmetric]) + from `finite A` show "finite (f ` A)" by simp + from assms show "f (Min A) \ f ` A" by simp + fix x + assume "x \ f ` A" + then obtain y where "y \ A" and "x = f y" .. + with assms have "Min A \ y" by auto + with `mono f` have "f (Min A) \ f y" by (rule monoE) + with `x = f y` show "f (Min A) \ x" by simp +qed -lemma finite_linorder_max_induct[consumes 1, case_names empty insert]: - assumes fin: "finite A" - and empty: "P {}" - and insert: "(!!b A. finite A \ ALL a:A. a < b \ P A \ P(insert b A))" - shows "P A" +lemma mono_Max_commute: + assumes "mono f" + assumes "finite A" and "A \ {}" + shows "f (Max A) = Max (f ` A)" +proof (rule linorder_class.Max_eqI [symmetric]) + from `finite A` show "finite (f ` A)" by simp + from assms show "f (Max A) \ f ` A" by simp + fix x + assume "x \ f ` A" + then obtain y where "y \ A" and "x = f y" .. + with assms have "y \ Max A" by auto + with `mono f` have "f y \ f (Max A)" by (rule monoE) + with `x = f y` show "x \ f (Max A)" by simp +qed + +lemma finite_linorder_max_induct [consumes 1, case_names empty insert]: + assumes fin: "finite A" + and empty: "P {}" + and insert: "\b A. finite A \ \a\A. a < b \ P A \ P (insert b A)" + shows "P A" using fin empty insert proof (induct rule: finite_psubset_induct) case (psubset A) @@ -1751,16 +2076,16 @@ assume "A \ {}" with `finite A` have "Max A : A" by auto then have A: "?A = A" using insert_Diff_single insert_absorb by auto - then have "P ?B" using `P {}` step IH[of ?B] by blast + then have "P ?B" using `P {}` step IH [of ?B] by blast moreover have "\a\?B. a < Max A" using Max_ge [OF `finite A`] by fastforce - ultimately show "P A" using A insert_Diff_single step[OF `finite ?B`] by fastforce + ultimately show "P A" using A insert_Diff_single step [OF `finite ?B`] by fastforce qed qed -lemma finite_linorder_min_induct[consumes 1, case_names empty insert]: - "\finite A; P {}; \b A. \finite A; \a\A. b < a; P A\ \ P (insert b A)\ \ P A" -by(rule linorder.finite_linorder_max_induct[OF dual_linorder]) +lemma finite_linorder_min_induct [consumes 1, case_names empty insert]: + "\finite A; P {}; \b A. \finite A; \a\A. b < a; P A\ \ P (insert b A)\ \ P A" + by (rule linorder.finite_linorder_max_induct [OF dual_linorder]) end @@ -1799,29 +2124,14 @@ begin lemma minus_Max_eq_Min [simp]: - "finite S \ S \ {} \ - (Max S) = Min (uminus ` S)" + "finite S \ S \ {} \ - Max S = Min (uminus ` S)" by (induct S rule: finite_ne_induct) (simp_all add: minus_max_eq_min) lemma minus_Min_eq_Max [simp]: - "finite S \ S \ {} \ - (Min S) = Max (uminus ` S)" + "finite S \ S \ {} \ - Min S = Max (uminus ` S)" by (induct S rule: finite_ne_induct) (simp_all add: minus_min_eq_max) end -lemma (in linorder) mono_Max_commute: - assumes "mono f" - assumes "finite A" and "A \ {}" - shows "f (Max A) = Max (f ` A)" -proof (rule linorder_class.Max_eqI [symmetric]) - from `finite A` show "finite (f ` A)" by simp - from assms show "f (Max A) \ f ` A" by simp - fix x - assume "x \ f ` A" - then obtain y where "y \ A" and "x = f y" .. - with assms have "y \ Max A" by auto - with `mono f` have "f y \ f (Max A)" by (rule monoE) - with `x = f y` show "x \ f (Max A)" by simp -qed (* FIXME augment also dual rule mono_Min_commute *) - end diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Complete_Lattices.thy --- a/src/HOL/Complete_Lattices.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Complete_Lattices.thy Sat Mar 23 20:50:39 2013 +0100 @@ -514,10 +514,10 @@ by (rule class.complete_linorder.intro, rule dual_complete_lattice, rule dual_linorder) lemma complete_linorder_inf_min: "inf = min" - by (rule ext)+ (auto intro: antisym) + by (rule ext)+ (auto intro: antisym simp add: min_def) lemma complete_linorder_sup_max: "sup = max" - by (rule ext)+ (auto intro: antisym) + by (rule ext)+ (auto intro: antisym simp add: max_def) lemma Inf_less_iff: "\S \ a \ (\x\S. x \ a)" diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Finite_Set.thy --- a/src/HOL/Finite_Set.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Finite_Set.thy Sat Mar 23 20:50:39 2013 +0100 @@ -564,9 +564,13 @@ assumes comp_fun_commute: "f y \ f x = f x \ f y" begin -lemma fun_left_comm: "f x (f y z) = f y (f x z)" +lemma fun_left_comm: "f y (f x z) = f x (f y z)" using comp_fun_commute by (simp add: fun_eq_iff) +lemma commute_left_comp: + "f y \ (f x \ g) = f x \ (f y \ g)" + by (simp add: o_assoc comp_fun_commute) + end inductive fold_graph :: "('a \ 'b \ 'b) \ 'b \ 'a set \ 'b \ bool" @@ -578,7 +582,7 @@ inductive_cases empty_fold_graphE [elim!]: "fold_graph f z {} x" definition fold :: "('a \ 'b \ 'b) \ 'b \ 'a set \ 'b" where - "fold f z A = (THE y. fold_graph f z A y)" + "fold f z A = (if finite A then (THE y. fold_graph f z A y) else z)" text{*A tempting alternative for the definiens is @{term "if finite A then THE y. fold_graph f z A y else e"}. @@ -595,6 +599,11 @@ context comp_fun_commute begin +lemma fold_graph_finite: + assumes "fold_graph f z A y" + shows "finite A" + using assms by induct simp_all + lemma fold_graph_insertE_aux: "fold_graph f z A y \ a \ A \ \y'. y = f a y' \ fold_graph f z (A - {a}) y'" proof (induct set: fold_graph) @@ -632,7 +641,7 @@ lemma fold_equality: "fold_graph f z A y \ fold f z A = y" -by (unfold fold_def) (blast intro: fold_graph_determ) + by (cases "finite A") (auto simp add: fold_def intro: fold_graph_determ dest: fold_graph_finite) lemma fold_graph_fold: assumes "finite A" @@ -642,13 +651,19 @@ moreover note fold_graph_determ ultimately have "\!x. fold_graph f z A x" by (rule ex_ex1I) then have "fold_graph f z A (The (fold_graph f z A))" by (rule theI') - then show ?thesis by (unfold fold_def) + with assms show ?thesis by (simp add: fold_def) qed -text{* The base case for @{text fold}: *} +text {* The base case for @{text fold}: *} -lemma (in -) fold_empty [simp]: "fold f z {} = z" -by (unfold fold_def) blast +lemma (in -) fold_infinite [simp]: + assumes "\ finite A" + shows "fold f z A = z" + using assms by (auto simp add: fold_def) + +lemma (in -) fold_empty [simp]: + "fold f z {} = z" + by (auto simp add: fold_def) text{* The various recursion equations for @{const fold}: *} @@ -656,22 +671,27 @@ assumes "finite A" and "x \ A" shows "fold f z (insert x A) = f x (fold f z A)" proof (rule fold_equality) + fix z from `finite A` have "fold_graph f z A (fold f z A)" by (rule fold_graph_fold) - with `x \ A`show "fold_graph f z (insert x A) (f x (fold f z A))" by (rule fold_graph.insertI) + with `x \ A` have "fold_graph f z (insert x A) (f x (fold f z A))" by (rule fold_graph.insertI) + then show "fold_graph f z (insert x A) (f x (fold f z A))" by simp qed -lemma fold_fun_comm: +declare (in -) empty_fold_graphE [rule del] fold_graph.intros [rule del] + -- {* No more proofs involve these. *} + +lemma fold_fun_left_comm: "finite A \ f x (fold f z A) = fold f (f x z) A" proof (induct rule: finite_induct) case empty then show ?case by simp next case (insert y A) then show ?case - by (simp add: fun_left_comm[of x]) + by (simp add: fun_left_comm [of x]) qed lemma fold_insert2: - "finite A \ x \ A \ fold f z (insert x A) = fold f (f x z) A" -by (simp add: fold_fun_comm) + "finite A \ x \ A \ fold f z (insert x A) = fold f (f x z) A" + by (simp add: fold_fun_left_comm) lemma fold_rec: assumes "finite A" and "x \ A" @@ -699,23 +719,23 @@ lemma fold_image: assumes "finite A" and "inj_on g A" - shows "fold f x (g ` A) = fold (f \ g) x A" + shows "fold f z (g ` A) = fold (f \ g) z A" using assms proof induction case (insert a F) interpret comp_fun_commute "\x. f (g x)" by default (simp add: comp_fun_commute) from insert show ?case by auto -qed (simp) +qed simp end lemma fold_cong: assumes "comp_fun_commute f" "comp_fun_commute g" assumes "finite A" and cong: "\x. x \ A \ f x = g x" - and "A = B" and "s = t" - shows "Finite_Set.fold f s A = Finite_Set.fold g t B" + and "s = t" and "A = B" + shows "fold f s A = fold g t B" proof - - have "Finite_Set.fold f s A = Finite_Set.fold g s A" + have "fold f s A = fold g s A" using `finite A` cong proof (induct A) case empty then show ?case by simp next @@ -728,10 +748,10 @@ qed -text{* A simplified version for idempotent functions: *} +text {* A simplified version for idempotent functions: *} locale comp_fun_idem = comp_fun_commute + - assumes comp_fun_idem: "f x o f x = f x" + assumes comp_fun_idem: "f x \ f x = f x" begin lemma fun_left_idem: "f x (f x z) = f x z" @@ -739,20 +759,20 @@ lemma fold_insert_idem: assumes fin: "finite A" - shows "fold f z (insert x A) = f x (fold f z A)" + shows "fold f z (insert x A) = f x (fold f z A)" proof cases assume "x \ A" then obtain B where "A = insert x B" and "x \ B" by (rule set_insert) - then show ?thesis using assms by (simp add:fun_left_idem) + then show ?thesis using assms by (simp add: comp_fun_idem fun_left_idem) next assume "x \ A" then show ?thesis using assms by simp qed -declare fold_insert[simp del] fold_insert_idem[simp] +declare fold_insert [simp del] fold_insert_idem [simp] lemma fold_insert_idem2: "finite A \ fold f z (insert x A) = fold f (f x z) A" -by(simp add:fold_fun_comm) + by (simp add: fold_fun_left_comm) end @@ -810,6 +830,11 @@ subsubsection {* Expressing set operations via @{const fold} *} +lemma comp_fun_commute_const: + "comp_fun_commute (\_. f)" +proof +qed rule + lemma comp_fun_idem_insert: "comp_fun_idem insert" proof @@ -847,7 +872,8 @@ then show ?thesis .. qed -lemma comp_fun_commute_filter_fold: "comp_fun_commute (\x A'. if P x then Set.insert x A' else A')" +lemma comp_fun_commute_filter_fold: + "comp_fun_commute (\x A'. if P x then Set.insert x A' else A')" proof - interpret comp_fun_idem Set.insert by (fact comp_fun_idem_insert) show ?thesis by default (auto simp: fun_eq_iff) @@ -916,13 +942,13 @@ lemma comp_fun_commute_product_fold: assumes "finite B" - shows "comp_fun_commute (\x A. fold (\y. Set.insert (x, y)) A B)" + shows "comp_fun_commute (\x z. fold (\y. Set.insert (x, y)) z B)" by default (auto simp: fold_union_pair[symmetric] assms) lemma product_fold: assumes "finite A" assumes "finite B" - shows "A \ B = fold (\x A. fold (\y. Set.insert (x, y)) A B) {} A" + shows "A \ B = fold (\x z. fold (\y. Set.insert (x, y)) z B) {} A" using assms unfolding Sigma_def by (induct A) (simp_all add: comp_fun_commute.fold_insert[OF comp_fun_commute_product_fold] fold_union_pair) @@ -933,20 +959,20 @@ lemma inf_Inf_fold_inf: assumes "finite A" - shows "inf B (Inf A) = fold inf B A" + shows "inf (Inf A) B = fold inf B A" proof - interpret comp_fun_idem inf by (fact comp_fun_idem_inf) - from `finite A` show ?thesis by (induct A arbitrary: B) - (simp_all add: inf_commute fold_fun_comm) + from `finite A` fold_fun_left_comm show ?thesis by (induct A arbitrary: B) + (simp_all add: inf_commute fun_eq_iff) qed lemma sup_Sup_fold_sup: assumes "finite A" - shows "sup B (Sup A) = fold sup B A" + shows "sup (Sup A) B = fold sup B A" proof - interpret comp_fun_idem sup by (fact comp_fun_idem_sup) - from `finite A` show ?thesis by (induct A arbitrary: B) - (simp_all add: sup_commute fold_fun_comm) + from `finite A` fold_fun_left_comm show ?thesis by (induct A arbitrary: B) + (simp_all add: sup_commute fun_eq_iff) qed lemma Inf_fold_inf: @@ -994,503 +1020,42 @@ end -subsection {* The derived combinator @{text fold_image} *} - -definition fold_image :: "('b \ 'b \ 'b) \ ('a \ 'b) \ 'b \ 'a set \ 'b" - where "fold_image f g = fold (\x y. f (g x) y)" - -lemma fold_image_empty[simp]: "fold_image f g z {} = z" - by (simp add:fold_image_def) - -context ab_semigroup_mult -begin - -lemma fold_image_insert[simp]: - assumes "finite A" and "a \ A" - shows "fold_image times g z (insert a A) = g a * (fold_image times g z A)" -proof - - interpret comp_fun_commute "%x y. (g x) * y" - by default (simp add: fun_eq_iff mult_ac) - from assms show ?thesis by (simp add: fold_image_def) -qed - -lemma fold_image_reindex: - assumes "finite A" - shows "inj_on h A \ fold_image times g z (h ` A) = fold_image times (g \ h) z A" - using assms by induct auto - -lemma fold_image_cong: - assumes "finite A" and g_h: "\x. x\A \ g x = h x" - shows "fold_image times g z A = fold_image times h z A" -proof - - from `finite A` - have "\C. C <= A --> (ALL x:C. g x = h x) --> fold_image times g z C = fold_image times h z C" - proof (induct arbitrary: C) - case empty then show ?case by simp - next - case (insert x F) then show ?case apply - - apply (simp add: subset_insert_iff, clarify) - apply (subgoal_tac "finite C") - prefer 2 apply (blast dest: finite_subset [rotated]) - apply (subgoal_tac "C = insert x (C - {x})") - prefer 2 apply blast - apply (erule ssubst) - apply (simp add: Ball_def del: insert_Diff_single) - done - qed - with g_h show ?thesis by simp -qed - -end - -context comm_monoid_mult -begin - -lemma fold_image_1: - "finite S \ (\x\S. f x = 1) \ fold_image op * f 1 S = 1" - apply (induct rule: finite_induct) - apply simp by auto - -lemma fold_image_Un_Int: - "finite A ==> finite B ==> - fold_image times g 1 A * fold_image times g 1 B = - fold_image times g 1 (A Un B) * fold_image times g 1 (A Int B)" - apply (induct rule: finite_induct) -by (induct set: finite) - (auto simp add: mult_ac insert_absorb Int_insert_left) - -lemma fold_image_Un_one: - assumes fS: "finite S" and fT: "finite T" - and I0: "\x \ S\T. f x = 1" - shows "fold_image (op *) f 1 (S \ T) = fold_image (op *) f 1 S * fold_image (op *) f 1 T" -proof- - have "fold_image op * f 1 (S \ T) = 1" - apply (rule fold_image_1) - using fS fT I0 by auto - with fold_image_Un_Int[OF fS fT] show ?thesis by simp -qed - -corollary fold_Un_disjoint: - "finite A ==> finite B ==> A Int B = {} ==> - fold_image times g 1 (A Un B) = - fold_image times g 1 A * fold_image times g 1 B" -by (simp add: fold_image_Un_Int) - -lemma fold_image_UN_disjoint: - "\ finite I; ALL i:I. finite (A i); - ALL i:I. ALL j:I. i \ j --> A i Int A j = {} \ - \ fold_image times g 1 (UNION I A) = - fold_image times (%i. fold_image times g 1 (A i)) 1 I" -apply (induct rule: finite_induct) -apply simp -apply atomize -apply (subgoal_tac "ALL i:F. x \ i") - prefer 2 apply blast -apply (subgoal_tac "A x Int UNION F A = {}") - prefer 2 apply blast -apply (simp add: fold_Un_disjoint) -done - -lemma fold_image_Sigma: "finite A ==> ALL x:A. finite (B x) ==> - fold_image times (%x. fold_image times (g x) 1 (B x)) 1 A = - fold_image times (split g) 1 (SIGMA x:A. B x)" -apply (subst Sigma_def) -apply (subst fold_image_UN_disjoint, assumption, simp) - apply blast -apply (erule fold_image_cong) -apply (subst fold_image_UN_disjoint, simp, simp) - apply blast -apply simp -done - -lemma fold_image_distrib: "finite A \ - fold_image times (%x. g x * h x) 1 A = - fold_image times g 1 A * fold_image times h 1 A" -by (erule finite_induct) (simp_all add: mult_ac) - -lemma fold_image_related: - assumes Re: "R e e" - and Rop: "\x1 y1 x2 y2. R x1 x2 \ R y1 y2 \ R (x1 * y1) (x2 * y2)" - and fS: "finite S" and Rfg: "\x\S. R (h x) (g x)" - shows "R (fold_image (op *) h e S) (fold_image (op *) g e S)" - using fS by (rule finite_subset_induct) (insert assms, auto) - -lemma fold_image_eq_general: - assumes fS: "finite S" - and h: "\y\S'. \!x. x\ S \ h(x) = y" - and f12: "\x\S. h x \ S' \ f2(h x) = f1 x" - shows "fold_image (op *) f1 e S = fold_image (op *) f2 e S'" -proof- - from h f12 have hS: "h ` S = S'" by auto - {fix x y assume H: "x \ S" "y \ S" "h x = h y" - from f12 h H have "x = y" by auto } - hence hinj: "inj_on h S" unfolding inj_on_def Ex1_def by blast - from f12 have th: "\x. x \ S \ (f2 \ h) x = f1 x" by auto - from hS have "fold_image (op *) f2 e S' = fold_image (op *) f2 e (h ` S)" by simp - also have "\ = fold_image (op *) (f2 o h) e S" - using fold_image_reindex[OF fS hinj, of f2 e] . - also have "\ = fold_image (op *) f1 e S " using th fold_image_cong[OF fS, of "f2 o h" f1 e] - by blast - finally show ?thesis .. -qed - -lemma fold_image_eq_general_inverses: - assumes fS: "finite S" - and kh: "\y. y \ T \ k y \ S \ h (k y) = y" - and hk: "\x. x \ S \ h x \ T \ k (h x) = x \ g (h x) = f x" - shows "fold_image (op *) f e S = fold_image (op *) g e T" - (* metis solves it, but not yet available here *) - apply (rule fold_image_eq_general[OF fS, of T h g f e]) - apply (rule ballI) - apply (frule kh) - apply (rule ex1I[]) - apply blast - apply clarsimp - apply (drule hk) apply simp - apply (rule sym) - apply (erule conjunct1[OF conjunct2[OF hk]]) - apply (rule ballI) - apply (drule hk) - apply blast - done - -end - - -subsection {* A fold functional for non-empty sets *} - -text{* Does not require start value. *} - -inductive - fold1Set :: "('a => 'a => 'a) => 'a set => 'a => bool" - for f :: "'a => 'a => 'a" -where - fold1Set_insertI [intro]: - "\ fold_graph f a A x; a \ A \ \ fold1Set f (insert a A) x" - -definition fold1 :: "('a => 'a => 'a) => 'a set => 'a" where - "fold1 f A == THE x. fold1Set f A x" - -lemma fold1Set_nonempty: - "fold1Set f A x \ A \ {}" -by(erule fold1Set.cases, simp_all) - -inductive_cases empty_fold1SetE [elim!]: "fold1Set f {} x" - -inductive_cases insert_fold1SetE [elim!]: "fold1Set f (insert a X) x" - - -lemma fold1Set_sing [iff]: "(fold1Set f {a} b) = (a = b)" -by (blast elim: fold_graph.cases) - -lemma fold1_singleton [simp]: "fold1 f {a} = a" -by (unfold fold1_def) blast - -lemma finite_nonempty_imp_fold1Set: - "\ finite A; A \ {} \ \ EX x. fold1Set f A x" -apply (induct A rule: finite_induct) -apply (auto dest: finite_imp_fold_graph [of _ f]) -done - -text{*First, some lemmas about @{const fold_graph}.*} - -context ab_semigroup_mult -begin - -lemma comp_fun_commute: "comp_fun_commute (op *)" - by default (simp add: fun_eq_iff mult_ac) - -lemma fold_graph_insert_swap: -assumes fold: "fold_graph times (b::'a) A y" and "b \ A" -shows "fold_graph times z (insert b A) (z * y)" -proof - - interpret comp_fun_commute "op *::'a \ 'a \ 'a" by (rule comp_fun_commute) -from assms show ?thesis -proof (induct rule: fold_graph.induct) - case emptyI show ?case by (subst mult_commute [of z b], fast) -next - case (insertI x A y) - have "fold_graph times z (insert x (insert b A)) (x * (z * y))" - using insertI by force --{*how does @{term id} get unfolded?*} - thus ?case by (simp add: insert_commute mult_ac) -qed -qed - -lemma fold_graph_permute_diff: -assumes fold: "fold_graph times b A x" -shows "!!a. \a \ A; b \ A\ \ fold_graph times a (insert b (A-{a})) x" -using fold -proof (induct rule: fold_graph.induct) - case emptyI thus ?case by simp -next - case (insertI x A y) - have "a = x \ a \ A" using insertI by simp - thus ?case - proof - assume "a = x" - with insertI show ?thesis - by (simp add: id_def [symmetric], blast intro: fold_graph_insert_swap) - next - assume ainA: "a \ A" - hence "fold_graph times a (insert x (insert b (A - {a}))) (x * y)" - using insertI by force - moreover - have "insert x (insert b (A - {a})) = insert b (insert x A - {a})" - using ainA insertI by blast - ultimately show ?thesis by simp - qed -qed - -lemma fold1_eq_fold: -assumes "finite A" "a \ A" shows "fold1 times (insert a A) = fold times a A" -proof - - interpret comp_fun_commute "op *::'a \ 'a \ 'a" by (rule comp_fun_commute) - from assms show ?thesis -apply (simp add: fold1_def fold_def) -apply (rule the_equality) -apply (best intro: fold_graph_determ theI dest: finite_imp_fold_graph [of _ times]) -apply (rule sym, clarify) -apply (case_tac "Aa=A") - apply (best intro: fold_graph_determ) -apply (subgoal_tac "fold_graph times a A x") - apply (best intro: fold_graph_determ) -apply (subgoal_tac "insert aa (Aa - {a}) = A") - prefer 2 apply (blast elim: equalityE) -apply (auto dest: fold_graph_permute_diff [where a=a]) -done -qed - -lemma nonempty_iff: "(A \ {}) = (\x B. A = insert x B & x \ B)" -apply safe - apply simp - apply (drule_tac x=x in spec) - apply (drule_tac x="A-{x}" in spec, auto) -done - -lemma fold1_insert: - assumes nonempty: "A \ {}" and A: "finite A" "x \ A" - shows "fold1 times (insert x A) = x * fold1 times A" -proof - - interpret comp_fun_commute "op *::'a \ 'a \ 'a" by (rule comp_fun_commute) - from nonempty obtain a A' where "A = insert a A' & a ~: A'" - by (auto simp add: nonempty_iff) - with A show ?thesis - by (simp add: insert_commute [of x] fold1_eq_fold eq_commute) -qed - -end - -class ab_semigroup_idem_mult = ab_semigroup_mult + - assumes mult_idem: "x * x = x" - -sublocale ab_semigroup_idem_mult < times!: semilattice times proof -qed (fact mult_idem) - -context ab_semigroup_idem_mult -begin - -lemmas mult_left_idem = times.left_idem - -lemma comp_fun_idem: "comp_fun_idem (op *)" - by default (simp_all add: fun_eq_iff mult_left_commute) - -lemma fold1_insert_idem [simp]: - assumes nonempty: "A \ {}" and A: "finite A" - shows "fold1 times (insert x A) = x * fold1 times A" -proof - - interpret comp_fun_idem "op *::'a \ 'a \ 'a" - by (rule comp_fun_idem) - from nonempty obtain a A' where A': "A = insert a A' & a ~: A'" - by (auto simp add: nonempty_iff) - show ?thesis - proof cases - assume a: "a = x" - show ?thesis - proof cases - assume "A' = {}" - with A' a show ?thesis by simp - next - assume "A' \ {}" - with A A' a show ?thesis - by (simp add: fold1_insert mult_assoc [symmetric]) - qed - next - assume "a \ x" - with A A' show ?thesis - by (simp add: insert_commute fold1_eq_fold) - qed -qed - -lemma hom_fold1_commute: -assumes hom: "!!x y. h (x * y) = h x * h y" -and N: "finite N" "N \ {}" shows "h (fold1 times N) = fold1 times (h ` N)" -using N -proof (induct rule: finite_ne_induct) - case singleton thus ?case by simp -next - case (insert n N) - then have "h (fold1 times (insert n N)) = h (n * fold1 times N)" by simp - also have "\ = h n * h (fold1 times N)" by(rule hom) - also have "h (fold1 times N) = fold1 times (h ` N)" by(rule insert) - also have "times (h n) \ = fold1 times (insert (h n) (h ` N))" - using insert by(simp) - also have "insert (h n) (h ` N) = h ` insert n N" by simp - finally show ?case . -qed - -lemma fold1_eq_fold_idem: - assumes "finite A" - shows "fold1 times (insert a A) = fold times a A" -proof (cases "a \ A") - case False - with assms show ?thesis by (simp add: fold1_eq_fold) -next - interpret comp_fun_idem times by (fact comp_fun_idem) - case True then obtain b B - where A: "A = insert a B" and "a \ B" by (rule set_insert) - with assms have "finite B" by auto - then have "fold times a (insert a B) = fold times (a * a) B" - using `a \ B` by (rule fold_insert2) - then show ?thesis - using `a \ B` `finite B` by (simp add: fold1_eq_fold A) -qed - -end - - -text{* Now the recursion rules for definitions: *} - -lemma fold1_singleton_def: "g = fold1 f \ g {a} = a" -by simp - -lemma (in ab_semigroup_mult) fold1_insert_def: - "\ g = fold1 times; finite A; x \ A; A \ {} \ \ g (insert x A) = x * g A" -by (simp add:fold1_insert) - -lemma (in ab_semigroup_idem_mult) fold1_insert_idem_def: - "\ g = fold1 times; finite A; A \ {} \ \ g (insert x A) = x * g A" -by simp - -subsubsection{* Determinacy for @{term fold1Set} *} - -(*Not actually used!!*) -(* -context ab_semigroup_mult -begin - -lemma fold_graph_permute: - "[|fold_graph times id b (insert a A) x; a \ A; b \ A|] - ==> fold_graph times id a (insert b A) x" -apply (cases "a=b") -apply (auto dest: fold_graph_permute_diff) -done - -lemma fold1Set_determ: - "fold1Set times A x ==> fold1Set times A y ==> y = x" -proof (clarify elim!: fold1Set.cases) - fix A x B y a b - assume Ax: "fold_graph times id a A x" - assume By: "fold_graph times id b B y" - assume anotA: "a \ A" - assume bnotB: "b \ B" - assume eq: "insert a A = insert b B" - show "y=x" - proof cases - assume same: "a=b" - hence "A=B" using anotA bnotB eq by (blast elim!: equalityE) - thus ?thesis using Ax By same by (blast intro: fold_graph_determ) - next - assume diff: "a\b" - let ?D = "B - {a}" - have B: "B = insert a ?D" and A: "A = insert b ?D" - and aB: "a \ B" and bA: "b \ A" - using eq anotA bnotB diff by (blast elim!:equalityE)+ - with aB bnotB By - have "fold_graph times id a (insert b ?D) y" - by (auto intro: fold_graph_permute simp add: insert_absorb) - moreover - have "fold_graph times id a (insert b ?D) x" - by (simp add: A [symmetric] Ax) - ultimately show ?thesis by (blast intro: fold_graph_determ) - qed -qed - -lemma fold1Set_equality: "fold1Set times A y ==> fold1 times A = y" - by (unfold fold1_def) (blast intro: fold1Set_determ) - -end -*) - -declare - empty_fold_graphE [rule del] fold_graph.intros [rule del] - empty_fold1SetE [rule del] insert_fold1SetE [rule del] - -- {* No more proofs involve these relations. *} - -subsubsection {* Lemmas about @{text fold1} *} - -context ab_semigroup_mult -begin - -lemma fold1_Un: -assumes A: "finite A" "A \ {}" -shows "finite B \ B \ {} \ A Int B = {} \ - fold1 times (A Un B) = fold1 times A * fold1 times B" -using A by (induct rule: finite_ne_induct) - (simp_all add: fold1_insert mult_assoc) - -lemma fold1_in: - assumes A: "finite (A)" "A \ {}" and elem: "\x y. x * y \ {x,y}" - shows "fold1 times A \ A" -using A -proof (induct rule:finite_ne_induct) - case singleton thus ?case by simp -next - case insert thus ?case using elem by (force simp add:fold1_insert) -qed - -end - -lemma (in ab_semigroup_idem_mult) fold1_Un2: -assumes A: "finite A" "A \ {}" -shows "finite B \ B \ {} \ - fold1 times (A Un B) = fold1 times A * fold1 times B" -using A -proof(induct rule:finite_ne_induct) - case singleton thus ?case by simp -next - case insert thus ?case by (simp add: mult_assoc) -qed - - subsection {* Locales as mini-packages for fold operations *} subsubsection {* The natural case *} locale folding = fixes f :: "'a \ 'b \ 'b" - fixes F :: "'a set \ 'b \ 'b" + fixes z :: "'b" assumes comp_fun_commute: "f y \ f x = f x \ f y" - assumes eq_fold: "finite A \ F A s = fold f s A" begin +definition F :: "'a set \ 'b" +where + eq_fold: "F A = fold f z A" + lemma empty [simp]: - "F {} = id" - by (simp add: eq_fold fun_eq_iff) + "F {} = z" + by (simp add: eq_fold) +lemma infinite [simp]: + "\ finite A \ F A = z" + by (simp add: eq_fold) + lemma insert [simp]: assumes "finite A" and "x \ A" - shows "F (insert x A) = F A \ f x" + shows "F (insert x A) = f x (F A)" proof - interpret comp_fun_commute f by default (insert comp_fun_commute, simp add: fun_eq_iff) - from fold_insert2 assms - have "\s. fold f s (insert x A) = fold f (f x s) A" . + from fold_insert assms + have "fold f z (insert x A) = f x (fold f z A)" by simp with `finite A` show ?thesis by (simp add: eq_fold fun_eq_iff) qed - + lemma remove: assumes "finite A" and "x \ A" - shows "F A = F (A - {x}) \ f x" + shows "F A = f x (F (A - {x}))" proof - from `x \ A` obtain B where A: "A = insert x B" and "x \ B" by (auto dest: mk_disjoint_insert) @@ -1500,524 +1065,69 @@ lemma insert_remove: assumes "finite A" - shows "F (insert x A) = F (A - {x}) \ f x" + shows "F (insert x A) = f x (F (A - {x}))" using assms by (cases "x \ A") (simp_all add: remove insert_absorb) -lemma commute_left_comp: - "f y \ (f x \ g) = f x \ (f y \ g)" - by (simp add: o_assoc comp_fun_commute) - -lemma comp_fun_commute': - assumes "finite A" - shows "f x \ F A = F A \ f x" - using assms by (induct A) - (simp, simp del: o_apply add: o_assoc, simp del: o_apply add: comp_assoc comp_fun_commute) - -lemma commute_left_comp': - assumes "finite A" - shows "f x \ (F A \ g) = F A \ (f x \ g)" - using assms by (simp add: o_assoc comp_fun_commute') - -lemma comp_fun_commute'': - assumes "finite A" and "finite B" - shows "F B \ F A = F A \ F B" - using assms by (induct A) - (simp_all add: o_assoc, simp add: comp_assoc comp_fun_commute') - -lemma commute_left_comp'': - assumes "finite A" and "finite B" - shows "F B \ (F A \ g) = F A \ (F B \ g)" - using assms by (simp add: o_assoc comp_fun_commute'') - -lemmas comp_fun_commutes = comp_assoc comp_fun_commute commute_left_comp - comp_fun_commute' commute_left_comp' comp_fun_commute'' commute_left_comp'' - -lemma union_inter: - assumes "finite A" and "finite B" - shows "F (A \ B) \ F (A \ B) = F A \ F B" - using assms by (induct A) - (simp_all del: o_apply add: insert_absorb Int_insert_left comp_fun_commutes, - simp add: o_assoc) - -lemma union: - assumes "finite A" and "finite B" - and "A \ B = {}" - shows "F (A \ B) = F A \ F B" -proof - - from union_inter `finite A` `finite B` have "F (A \ B) \ F (A \ B) = F A \ F B" . - with `A \ B = {}` show ?thesis by simp -qed - end -subsubsection {* The natural case with idempotency *} +subsubsection {* With idempotency *} locale folding_idem = folding + - assumes idem_comp: "f x \ f x = f x" + assumes comp_fun_idem: "f x \ f x = f x" begin -lemma idem_left_comp: - "f x \ (f x \ g) = f x \ g" - by (simp add: o_assoc idem_comp) - -lemma in_comp_idem: - assumes "finite A" and "x \ A" - shows "F A \ f x = F A" -using assms by (induct A) - (auto simp add: comp_fun_commutes idem_comp, simp add: commute_left_comp' [symmetric] comp_fun_commute') - -lemma subset_comp_idem: - assumes "finite A" and "B \ A" - shows "F A \ F B = F A" -proof - - from assms have "finite B" by (blast dest: finite_subset) - then show ?thesis using `B \ A` by (induct B) - (simp_all add: o_assoc in_comp_idem `finite A`) -qed - declare insert [simp del] lemma insert_idem [simp]: assumes "finite A" - shows "F (insert x A) = F A \ f x" - using assms by (cases "x \ A") (simp_all add: insert in_comp_idem insert_absorb) - -lemma union_idem: - assumes "finite A" and "finite B" - shows "F (A \ B) = F A \ F B" + shows "F (insert x A) = f x (F A)" proof - - from assms have "finite (A \ B)" and "A \ B \ A \ B" by auto - then have "F (A \ B) \ F (A \ B) = F (A \ B)" by (rule subset_comp_idem) - with assms show ?thesis by (simp add: union_inter) + interpret comp_fun_idem f + by default (insert comp_fun_commute comp_fun_idem, simp add: fun_eq_iff) + from fold_insert_idem assms + have "fold f z (insert x A) = f x (fold f z A)" by simp + with `finite A` show ?thesis by (simp add: eq_fold fun_eq_iff) qed end -subsubsection {* The image case with fixed function *} - -no_notation times (infixl "*" 70) -no_notation Groups.one ("1") - -locale folding_image_simple = comm_monoid + - fixes g :: "('b \ 'a)" - fixes F :: "'b set \ 'a" - assumes eq_fold_g: "finite A \ F A = fold_image f g 1 A" -begin - -lemma empty [simp]: - "F {} = 1" - by (simp add: eq_fold_g) - -lemma insert [simp]: - assumes "finite A" and "x \ A" - shows "F (insert x A) = g x * F A" -proof - - interpret comp_fun_commute "%x y. (g x) * y" - by default (simp add: ac_simps fun_eq_iff) - from assms have "fold_image (op *) g 1 (insert x A) = g x * fold_image (op *) g 1 A" - by (simp add: fold_image_def) - with `finite A` show ?thesis by (simp add: eq_fold_g) -qed - -lemma remove: - assumes "finite A" and "x \ A" - shows "F A = g x * F (A - {x})" -proof - - from `x \ A` obtain B where A: "A = insert x B" and "x \ B" - by (auto dest: mk_disjoint_insert) - moreover from `finite A` this have "finite B" by simp - ultimately show ?thesis by simp -qed - -lemma insert_remove: - assumes "finite A" - shows "F (insert x A) = g x * F (A - {x})" - using assms by (cases "x \ A") (simp_all add: remove insert_absorb) - -lemma neutral: - assumes "finite A" and "\x\A. g x = 1" - shows "F A = 1" - using assms by (induct A) simp_all - -lemma union_inter: - assumes "finite A" and "finite B" - shows "F (A \ B) * F (A \ B) = F A * F B" -using assms proof (induct A) - case empty then show ?case by simp -next - case (insert x A) then show ?case - by (auto simp add: insert_absorb Int_insert_left commute [of _ "g x"] assoc left_commute) -qed - -corollary union_inter_neutral: - assumes "finite A" and "finite B" - and I0: "\x \ A\B. g x = 1" - shows "F (A \ B) = F A * F B" - using assms by (simp add: union_inter [symmetric] neutral) - -corollary union_disjoint: - assumes "finite A" and "finite B" - assumes "A \ B = {}" - shows "F (A \ B) = F A * F B" - using assms by (simp add: union_inter_neutral) - -end - - -subsubsection {* The image case with flexible function *} - -locale folding_image = comm_monoid + - fixes F :: "('b \ 'a) \ 'b set \ 'a" - assumes eq_fold: "\g. finite A \ F g A = fold_image f g 1 A" - -sublocale folding_image < folding_image_simple "op *" 1 g "F g" proof -qed (fact eq_fold) - -context folding_image -begin - -lemma reindex: (* FIXME polymorhism *) - assumes "finite A" and "inj_on h A" - shows "F g (h ` A) = F (g \ h) A" - using assms by (induct A) auto - -lemma cong: - assumes "finite A" and "\x. x \ A \ g x = h x" - shows "F g A = F h A" -proof - - from assms have "ALL C. C <= A --> (ALL x:C. g x = h x) --> F g C = F h C" - apply - apply (erule finite_induct) apply simp - apply (simp add: subset_insert_iff, clarify) - apply (subgoal_tac "finite C") - prefer 2 apply (blast dest: finite_subset [rotated]) - apply (subgoal_tac "C = insert x (C - {x})") - prefer 2 apply blast - apply (erule ssubst) - apply (drule spec) - apply (erule (1) notE impE) - apply (simp add: Ball_def del: insert_Diff_single) - done - with assms show ?thesis by simp -qed - -lemma UNION_disjoint: - assumes "finite I" and "\i\I. finite (A i)" - and "\i\I. \j\I. i \ j \ A i \ A j = {}" - shows "F g (UNION I A) = F (F g \ A) I" -apply (insert assms) -apply (induct rule: finite_induct) -apply simp -apply atomize -apply (subgoal_tac "\i\Fa. x \ i") - prefer 2 apply blast -apply (subgoal_tac "A x Int UNION Fa A = {}") - prefer 2 apply blast -apply (simp add: union_disjoint) -done - -lemma distrib: - assumes "finite A" - shows "F (\x. g x * h x) A = F g A * F h A" - using assms by (rule finite_induct) (simp_all add: assoc commute left_commute) - -lemma related: - assumes Re: "R 1 1" - and Rop: "\x1 y1 x2 y2. R x1 x2 \ R y1 y2 \ R (x1 * y1) (x2 * y2)" - and fS: "finite S" and Rfg: "\x\S. R (h x) (g x)" - shows "R (F h S) (F g S)" - using fS by (rule finite_subset_induct) (insert assms, auto) - -lemma eq_general: - assumes fS: "finite S" - and h: "\y\S'. \!x. x \ S \ h x = y" - and f12: "\x\S. h x \ S' \ f2 (h x) = f1 x" - shows "F f1 S = F f2 S'" -proof- - from h f12 have hS: "h ` S = S'" by blast - {fix x y assume H: "x \ S" "y \ S" "h x = h y" - from f12 h H have "x = y" by auto } - hence hinj: "inj_on h S" unfolding inj_on_def Ex1_def by blast - from f12 have th: "\x. x \ S \ (f2 \ h) x = f1 x" by auto - from hS have "F f2 S' = F f2 (h ` S)" by simp - also have "\ = F (f2 o h) S" using reindex [OF fS hinj, of f2] . - also have "\ = F f1 S " using th cong [OF fS, of "f2 o h" f1] - by blast - finally show ?thesis .. -qed - -lemma eq_general_inverses: - assumes fS: "finite S" - and kh: "\y. y \ T \ k y \ S \ h (k y) = y" - and hk: "\x. x \ S \ h x \ T \ k (h x) = x \ g (h x) = j x" - shows "F j S = F g T" - (* metis solves it, but not yet available here *) - apply (rule eq_general [OF fS, of T h g j]) - apply (rule ballI) - apply (frule kh) - apply (rule ex1I[]) - apply blast - apply clarsimp - apply (drule hk) apply simp - apply (rule sym) - apply (erule conjunct1[OF conjunct2[OF hk]]) - apply (rule ballI) - apply (drule hk) - apply blast - done - -end - - -subsubsection {* The image case with fixed function and idempotency *} - -locale folding_image_simple_idem = folding_image_simple + - assumes idem: "x * x = x" - -sublocale folding_image_simple_idem < semilattice: semilattice proof -qed (fact idem) - -context folding_image_simple_idem -begin - -lemma in_idem: - assumes "finite A" and "x \ A" - shows "g x * F A = F A" - using assms by (induct A) (auto simp add: left_commute) - -lemma subset_idem: - assumes "finite A" and "B \ A" - shows "F B * F A = F A" -proof - - from assms have "finite B" by (blast dest: finite_subset) - then show ?thesis using `B \ A` by (induct B) - (auto simp add: assoc in_idem `finite A`) -qed - -declare insert [simp del] - -lemma insert_idem [simp]: - assumes "finite A" - shows "F (insert x A) = g x * F A" - using assms by (cases "x \ A") (simp_all add: insert in_idem insert_absorb) - -lemma union_idem: - assumes "finite A" and "finite B" - shows "F (A \ B) = F A * F B" -proof - - from assms have "finite (A \ B)" and "A \ B \ A \ B" by auto - then have "F (A \ B) * F (A \ B) = F (A \ B)" by (rule subset_idem) - with assms show ?thesis by (simp add: union_inter [of A B, symmetric] commute) -qed - -end - - -subsubsection {* The image case with flexible function and idempotency *} - -locale folding_image_idem = folding_image + - assumes idem: "x * x = x" - -sublocale folding_image_idem < folding_image_simple_idem "op *" 1 g "F g" proof -qed (fact idem) - - -subsubsection {* The neutral-less case *} - -locale folding_one = abel_semigroup + - fixes F :: "'a set \ 'a" - assumes eq_fold: "finite A \ F A = fold1 f A" -begin - -lemma singleton [simp]: - "F {x} = x" - by (simp add: eq_fold) - -lemma eq_fold': - assumes "finite A" and "x \ A" - shows "F (insert x A) = fold (op *) x A" -proof - - interpret ab_semigroup_mult "op *" by default (simp_all add: ac_simps) - from assms show ?thesis by (simp add: eq_fold fold1_eq_fold) -qed - -lemma insert [simp]: - assumes "finite A" and "x \ A" and "A \ {}" - shows "F (insert x A) = x * F A" -proof - - from `A \ {}` obtain b where "b \ A" by blast - then obtain B where *: "A = insert b B" "b \ B" by (blast dest: mk_disjoint_insert) - with `finite A` have "finite B" by simp - interpret fold: folding "op *" "\a b. fold (op *) b a" proof - qed (simp_all add: fun_eq_iff ac_simps) - from `finite B` fold.comp_fun_commute' [of B x] - have "op * x \ (\b. fold op * b B) = (\b. fold op * b B) \ op * x" by simp - then have A: "x * fold op * b B = fold op * (b * x) B" by (simp add: fun_eq_iff commute) - from `finite B` * fold.insert [of B b] - have "(\x. fold op * x (insert b B)) = (\x. fold op * x B) \ op * b" by simp - then have B: "fold op * x (insert b B) = fold op * (b * x) B" by (simp add: fun_eq_iff) - from A B assms * show ?thesis by (simp add: eq_fold' del: fold.insert) -qed - -lemma remove: - assumes "finite A" and "x \ A" - shows "F A = (if A - {x} = {} then x else x * F (A - {x}))" -proof - - from assms obtain B where "A = insert x B" and "x \ B" by (blast dest: mk_disjoint_insert) - with assms show ?thesis by simp -qed - -lemma insert_remove: - assumes "finite A" - shows "F (insert x A) = (if A - {x} = {} then x else x * F (A - {x}))" - using assms by (cases "x \ A") (simp_all add: insert_absorb remove) - -lemma union_disjoint: - assumes "finite A" "A \ {}" and "finite B" "B \ {}" and "A \ B = {}" - shows "F (A \ B) = F A * F B" - using assms by (induct A rule: finite_ne_induct) (simp_all add: ac_simps) - -lemma union_inter: - assumes "finite A" and "finite B" and "A \ B \ {}" - shows "F (A \ B) * F (A \ B) = F A * F B" -proof - - from assms have "A \ {}" and "B \ {}" by auto - from `finite A` `A \ {}` `A \ B \ {}` show ?thesis proof (induct A rule: finite_ne_induct) - case (singleton x) then show ?case by (simp add: insert_absorb ac_simps) - next - case (insert x A) show ?case proof (cases "x \ B") - case True then have "B \ {}" by auto - with insert True `finite B` show ?thesis by (cases "A \ B = {}") - (simp_all add: insert_absorb ac_simps union_disjoint) - next - case False with insert have "F (A \ B) * F (A \ B) = F A * F B" by simp - moreover from False `finite B` insert have "finite (A \ B)" "x \ A \ B" "A \ B \ {}" - by auto - ultimately show ?thesis using False `finite A` `x \ A` `A \ {}` by (simp add: assoc) - qed - qed -qed - -lemma closed: - assumes "finite A" "A \ {}" and elem: "\x y. x * y \ {x, y}" - shows "F A \ A" -using `finite A` `A \ {}` proof (induct rule: finite_ne_induct) - case singleton then show ?case by simp -next - case insert with elem show ?case by force -qed - -end - - -subsubsection {* The neutral-less case with idempotency *} - -locale folding_one_idem = folding_one + - assumes idem: "x * x = x" - -sublocale folding_one_idem < semilattice: semilattice proof -qed (fact idem) - -context folding_one_idem -begin - -lemma in_idem: - assumes "finite A" and "x \ A" - shows "x * F A = F A" -proof - - from assms have "A \ {}" by auto - with `finite A` show ?thesis using `x \ A` by (induct A rule: finite_ne_induct) (auto simp add: ac_simps) -qed - -lemma subset_idem: - assumes "finite A" "B \ {}" and "B \ A" - shows "F B * F A = F A" -proof - - from assms have "finite B" by (blast dest: finite_subset) - then show ?thesis using `B \ {}` `B \ A` by (induct B rule: finite_ne_induct) - (simp_all add: assoc in_idem `finite A`) -qed - -lemma eq_fold_idem': - assumes "finite A" - shows "F (insert a A) = fold (op *) a A" -proof - - interpret ab_semigroup_idem_mult "op *" by default (simp_all add: ac_simps) - from assms show ?thesis by (simp add: eq_fold fold1_eq_fold_idem) -qed - -lemma insert_idem [simp]: - assumes "finite A" and "A \ {}" - shows "F (insert x A) = x * F A" -proof (cases "x \ A") - case False from `finite A` `x \ A` `A \ {}` show ?thesis by (rule insert) -next - case True - from `finite A` `A \ {}` show ?thesis by (simp add: in_idem insert_absorb True) -qed - -lemma union_idem: - assumes "finite A" "A \ {}" and "finite B" "B \ {}" - shows "F (A \ B) = F A * F B" -proof (cases "A \ B = {}") - case True with assms show ?thesis by (simp add: union_disjoint) -next - case False - from assms have "finite (A \ B)" and "A \ B \ A \ B" by auto - with False have "F (A \ B) * F (A \ B) = F (A \ B)" by (auto intro: subset_idem) - with assms False show ?thesis by (simp add: union_inter [of A B, symmetric] commute) -qed - -lemma hom_commute: - assumes hom: "\x y. h (x * y) = h x * h y" - and N: "finite N" "N \ {}" shows "h (F N) = F (h ` N)" -using N proof (induct rule: finite_ne_induct) - case singleton thus ?case by simp -next - case (insert n N) - then have "h (F (insert n N)) = h (n * F N)" by simp - also have "\ = h n * h (F N)" by (rule hom) - also have "h (F N) = F (h ` N)" by(rule insert) - also have "h n * \ = F (insert (h n) (h ` N))" - using insert by(simp) - also have "insert (h n) (h ` N) = h ` insert n N" by simp - finally show ?case . -qed - -end - -notation times (infixl "*" 70) -notation Groups.one ("1") - - subsection {* Finite cardinality *} -text {* This definition, although traditional, is ugly to work with: -@{text "card A == LEAST n. EX f. A = {f i | i. i < n}"}. -But now that we have @{text fold_image} things are easy: +text {* + The traditional definition + @{prop "card A \ LEAST n. EX f. A = {f i | i. i < n}"} + is ugly to work with. + But now that we have @{const fold} things are easy: *} definition card :: "'a set \ nat" where - "card A = (if finite A then fold_image (op +) (\x. 1) 0 A else 0)" + "card = folding.F (\_. Suc) 0" -interpretation card: folding_image_simple "op +" 0 "\x. 1" card proof -qed (simp add: card_def) +interpretation card!: folding "\_. Suc" 0 +where + "card.F = card" +proof - + show "folding (\_. Suc)" by default rule + then interpret card!: folding "\_. Suc" 0 . + show "card.F = card" by (simp only: card_def) +qed -lemma card_infinite [simp]: +lemma card_infinite: "\ finite A \ card A = 0" - by (simp add: card_def) + by (fact card.infinite) lemma card_empty: "card {} = 0" by (fact card.empty) lemma card_insert_disjoint: - "finite A ==> x \ A ==> card (insert x A) = Suc (card A)" - by simp + "finite A \ x \ A \ card (insert x A) = Suc (card A)" + by (fact card.insert) lemma card_insert_if: - "finite A ==> card (insert x A) = (if x \ A then card A else Suc (card A))" + "finite A \ card (insert x A) = (if x \ A then card A else Suc (card A))" by auto (simp add: card.insert_remove card.remove) lemma card_ge_0_finite: @@ -2040,29 +1150,30 @@ "0 < card A \ A \ {} \ finite A" by (simp add: neq0_conv [symmetric] card_eq_0_iff) -lemma card_Suc_Diff1: "finite A ==> x: A ==> Suc (card (A - {x})) = card A" +lemma card_Suc_Diff1: + "finite A \ x \ A \ Suc (card (A - {x})) = card A" apply(rule_tac t = A in insert_Diff [THEN subst], assumption) apply(simp del:insert_Diff_single) done lemma card_Diff_singleton: - "finite A ==> x: A ==> card (A - {x}) = card A - 1" -by (simp add: card_Suc_Diff1 [symmetric]) + "finite A \ x \ A \ card (A - {x}) = card A - 1" + by (simp add: card_Suc_Diff1 [symmetric]) lemma card_Diff_singleton_if: - "finite A ==> card (A - {x}) = (if x : A then card A - 1 else card A)" -by (simp add: card_Diff_singleton) + "finite A \ card (A - {x}) = (if x \ A then card A - 1 else card A)" + by (simp add: card_Diff_singleton) lemma card_Diff_insert[simp]: -assumes "finite A" and "a:A" and "a ~: B" -shows "card(A - insert a B) = card(A - B) - 1" + assumes "finite A" and "a \ A" and "a \ B" + shows "card (A - insert a B) = card (A - B) - 1" proof - have "A - insert a B = (A - B) - {a}" using assms by blast - then show ?thesis using assms by(simp add:card_Diff_singleton) + then show ?thesis using assms by(simp add: card_Diff_singleton) qed lemma card_insert: "finite A ==> card (insert x A) = Suc (card (A - {x}))" -by (simp add: card_insert_if card_Suc_Diff1 del:card_Diff_insert) + by (fact card.insert_remove) lemma card_insert_le: "finite A ==> card A <= card (insert x A)" by (simp add: card_insert_if) @@ -2105,13 +1216,21 @@ apply (blast dest: card_seteq) done -lemma card_Un_Int: "finite A ==> finite B - ==> card A + card B = card (A Un B) + card (A Int B)" - by (fact card.union_inter [symmetric]) +lemma card_Un_Int: + assumes "finite A" and "finite B" + shows "card A + card B = card (A \ B) + card (A \ B)" +using assms proof (induct A) + case empty then show ?case by simp +next + case (insert x A) then show ?case + by (auto simp add: insert_absorb Int_insert_left) +qed -lemma card_Un_disjoint: "finite A ==> finite B - ==> A Int B = {} ==> card (A Un B) = card A + card B" - by (fact card.union_disjoint) +lemma card_Un_disjoint: + assumes "finite A" and "finite B" + assumes "A \ B = {}" + shows "card (A \ B) = card A + card B" +using assms card_Un_Int [of A B] by simp lemma card_Diff_subset: assumes "finite B" and "B \ A" @@ -2241,7 +1360,7 @@ apply(rule iffI) apply(erule card_eq_SucD) apply(auto) -apply(subst card_insert) +apply(subst card.insert) apply(auto intro:ccontr) done @@ -2439,25 +1558,26 @@ shows "finite(UNIV:: 'a set) \ inj f \ surj f" by(fastforce simp:surj_def dest!: endo_inj_surj) -corollary infinite_UNIV_nat[iff]: "~finite(UNIV::nat set)" +corollary infinite_UNIV_nat [iff]: + "\ finite (UNIV :: nat set)" proof - assume "finite(UNIV::nat set)" - with finite_UNIV_inj_surj[of Suc] + assume "finite (UNIV :: nat set)" + with finite_UNIV_inj_surj [of Suc] show False by simp (blast dest: Suc_neq_Zero surjD) qed (* Often leads to bogus ATP proofs because of reduced type information, hence no_atp *) -lemma infinite_UNIV_char_0[no_atp]: - "\ finite (UNIV::'a::semiring_char_0 set)" +lemma infinite_UNIV_char_0 [no_atp]: + "\ finite (UNIV :: 'a::semiring_char_0 set)" proof - assume "finite (UNIV::'a set)" - with subset_UNIV have "finite (range of_nat::'a set)" + assume "finite (UNIV :: 'a set)" + with subset_UNIV have "finite (range of_nat :: 'a set)" by (rule finite_subset) - moreover have "inj (of_nat::nat \ 'a)" + moreover have "inj (of_nat :: nat \ 'a)" by (simp add: inj_on_def) - ultimately have "finite (UNIV::nat set)" + ultimately have "finite (UNIV :: nat set)" by (rule finite_imageD) - then show "False" + then show False by simp qed diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/GCD.thy --- a/src/HOL/GCD.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/GCD.thy Sat Mar 23 20:50:39 2013 +0100 @@ -1462,6 +1462,10 @@ subsection {* The complete divisibility lattice *} +lemma semilattice_neutr_set_lcm_one_nat: + "semilattice_neutr_set lcm (1::nat)" + by default simp_all + interpretation gcd_semilattice_nat: semilattice_inf gcd "op dvd" "(%m n::nat. m dvd n & ~ n dvd m)" proof case goal3 thus ?case by(metis gcd_unique_nat) @@ -1486,33 +1490,62 @@ begin definition - "Lcm (M::nat set) = (if finite M then Finite_Set.fold lcm 1 M else 0)" + "Lcm (M::nat set) = (if finite M then semilattice_neutr_set.F lcm 1 M else 0)" + +lemma Lcm_nat_infinite: + "\ finite M \ Lcm M = (0::nat)" + by (simp add: Lcm_nat_def) + +lemma Lcm_nat_empty: + "Lcm {} = (1::nat)" +proof - + interpret semilattice_neutr_set lcm "1::nat" + by (fact semilattice_neutr_set_lcm_one_nat) + show ?thesis by (simp add: Lcm_nat_def) +qed + +lemma Lcm_nat_insert: + "Lcm (insert n M) = lcm (n::nat) (Lcm M)" +proof (cases "finite M") + interpret semilattice_neutr_set lcm "1::nat" + by (fact semilattice_neutr_set_lcm_one_nat) + case True + then show ?thesis by (simp add: Lcm_nat_def) +next + case False then show ?thesis by (simp add: Lcm_nat_infinite) +qed definition "Gcd (M::nat set) = Lcm {d. \m\M. d dvd m}" instance .. + end lemma dvd_Lcm_nat [simp]: - fixes M :: "nat set" assumes "m \ M" shows "m dvd Lcm M" - using lcm_semilattice_nat.sup_le_fold_sup[OF _ assms, of 1] - by (simp add: Lcm_nat_def) + fixes M :: "nat set" + assumes "m \ M" + shows "m dvd Lcm M" +proof (cases "finite M") + case False then show ?thesis by (simp add: Lcm_nat_infinite) +next + case True then show ?thesis using assms by (induct M) (auto simp add: Lcm_nat_insert) +qed lemma Lcm_dvd_nat [simp]: - fixes M :: "nat set" assumes "\m\M. m dvd n" shows "Lcm M dvd n" + fixes M :: "nat set" + assumes "\m\M. m dvd n" + shows "Lcm M dvd n" proof (cases "n = 0") assume "n \ 0" hence "finite {d. d dvd n}" by (rule finite_divisors_nat) moreover have "M \ {d. d dvd n}" using assms by fast ultimately have "finite M" by (rule rev_finite_subset) - thus ?thesis - using lcm_semilattice_nat.fold_sup_le_sup [OF _ assms, of 1] - by (simp add: Lcm_nat_def) + then show ?thesis using assms by (induct M) (simp_all add: Lcm_nat_empty Lcm_nat_insert) qed simp interpretation gcd_lcm_complete_lattice_nat: - complete_lattice Gcd Lcm gcd "op dvd" "%m n::nat. m dvd n & ~ n dvd m" lcm 1 0 + complete_lattice Gcd Lcm gcd "op dvd" "\m n::nat. m dvd n \ \ n dvd m" lcm 1 0 proof case goal1 show ?case by simp next diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/HOLCF/Compact_Basis.thy --- a/src/HOL/HOLCF/Compact_Basis.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/HOLCF/Compact_Basis.thy Sat Mar 23 20:50:39 2013 +0100 @@ -96,20 +96,23 @@ definition fold_pd :: "('a compact_basis \ 'b::type) \ ('b \ 'b \ 'b) \ 'a pd_basis \ 'b" - where "fold_pd g f t = fold1 f (g ` Rep_pd_basis t)" + where "fold_pd g f t = semilattice_set.F f (g ` Rep_pd_basis t)" lemma fold_pd_PDUnit: - assumes "class.ab_semigroup_idem_mult f" + assumes "semilattice f" shows "fold_pd g f (PDUnit x) = g x" -unfolding fold_pd_def Rep_PDUnit by simp +proof - + from assms interpret semilattice_set f by (rule semilattice_set.intro) + show ?thesis by (simp add: fold_pd_def Rep_PDUnit) +qed lemma fold_pd_PDPlus: - assumes "class.ab_semigroup_idem_mult f" + assumes "semilattice f" shows "fold_pd g f (PDPlus t u) = f (fold_pd g f t) (fold_pd g f u)" proof - - interpret ab_semigroup_idem_mult f by fact - show ?thesis unfolding fold_pd_def Rep_PDPlus - by (simp add: image_Un fold1_Un2) + from assms interpret semilattice_set f by (rule semilattice_set.intro) + show ?thesis by (simp add: image_Un fold_pd_def Rep_PDPlus union) qed end + diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/HOLCF/ConvexPD.thy --- a/src/HOL/HOLCF/ConvexPD.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/HOLCF/ConvexPD.thy Sat Mar 23 20:50:39 2013 +0100 @@ -316,7 +316,7 @@ (\x y. \ f. x\f \\ y\f)" lemma ACI_convex_bind: - "class.ab_semigroup_idem_mult (\x y. \ f. x\f \\ y\f)" + "semilattice (\x y. \ f. x\f \\ y\f)" apply unfold_locales apply (simp add: convex_plus_assoc) apply (simp add: convex_plus_commute) diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/HOLCF/LowerPD.thy --- a/src/HOL/HOLCF/LowerPD.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/HOLCF/LowerPD.thy Sat Mar 23 20:50:39 2013 +0100 @@ -309,7 +309,7 @@ (\x y. \ f. x\f \\ y\f)" lemma ACI_lower_bind: - "class.ab_semigroup_idem_mult (\x y. \ f. x\f \\ y\f)" + "semilattice (\x y. \ f. x\f \\ y\f)" apply unfold_locales apply (simp add: lower_plus_assoc) apply (simp add: lower_plus_commute) diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/HOLCF/UpperPD.thy --- a/src/HOL/HOLCF/UpperPD.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/HOLCF/UpperPD.thy Sat Mar 23 20:50:39 2013 +0100 @@ -302,7 +302,7 @@ (\x y. \ f. x\f \\ y\f)" lemma ACI_upper_bind: - "class.ab_semigroup_idem_mult (\x y. \ f. x\f \\ y\f)" + "semilattice (\x y. \ f. x\f \\ y\f)" apply unfold_locales apply (simp add: upper_plus_assoc) apply (simp add: upper_plus_commute) diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Lattices.thy --- a/src/HOL/Lattices.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Lattices.thy Sat Mar 23 20:50:39 2013 +0100 @@ -716,32 +716,6 @@ qed -subsection {* @{const min}/@{const max} on linear orders as - special case of @{const inf}/@{const sup} *} - -sublocale linorder < min_max!: distrib_lattice min less_eq less max -proof - fix x y z - show "max x (min y z) = min (max x y) (max x z)" - by (auto simp add: min_def max_def) -qed (auto simp add: min_def max_def not_le less_imp_le) - -lemma inf_min: "inf = (min \ 'a\{semilattice_inf, linorder} \ 'a \ 'a)" - by (rule ext)+ (auto intro: antisym) - -lemma sup_max: "sup = (max \ 'a\{semilattice_sup, linorder} \ 'a \ 'a)" - by (rule ext)+ (auto intro: antisym) - -lemmas le_maxI1 = min_max.sup_ge1 -lemmas le_maxI2 = min_max.sup_ge2 - -lemmas min_ac = min_max.inf_assoc min_max.inf_commute - min_max.inf.left_commute - -lemmas max_ac = min_max.sup_assoc min_max.sup_commute - min_max.sup.left_commute - - subsection {* Lattice on @{typ bool} *} instantiation bool :: boolean_algebra diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Library/Finite_Lattice.thy --- a/src/HOL/Library/Finite_Lattice.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Library/Finite_Lattice.thy Sat Mar 23 20:50:39 2013 +0100 @@ -39,6 +39,30 @@ by (metis finite_UNIV inf_Sup_absorb inf_top_left iso_tuple_UNIV_I) -- "Derived definition of @{const top}." +lemma finite_lattice_complete_Inf_empty: + "Inf {} = (top :: 'a::finite_lattice_complete)" + by (simp add: Inf_def) + +lemma finite_lattice_complete_Sup_empty: + "Sup {} = (bot :: 'a::finite_lattice_complete)" + by (simp add: Sup_def) + +lemma finite_lattice_complete_Inf_insert: + fixes A :: "'a::finite_lattice_complete set" + shows "Inf (insert x A) = inf x (Inf A)" +proof - + interpret comp_fun_idem "inf :: 'a \ _" by (fact comp_fun_idem_inf) + show ?thesis by (simp add: Inf_def) +qed + +lemma finite_lattice_complete_Sup_insert: + fixes A :: "'a::finite_lattice_complete set" + shows "Sup (insert x A) = sup x (Sup A)" +proof - + interpret comp_fun_idem "sup :: 'a \ _" by (fact comp_fun_idem_sup) + show ?thesis by (simp add: Sup_def) +qed + text {* The definitional assumptions on the operators @{const Inf} and @{const Sup} of class @{class finite_lattice_complete} @@ -47,19 +71,19 @@ lemma finite_lattice_complete_Inf_lower: "(x::'a::finite_lattice_complete) \ A \ Inf A \ x" -unfolding Inf_def by (metis finite_code le_inf_iff fold_inf_le_inf) + using finite [of A] by (induct A) (auto simp add: finite_lattice_complete_Inf_insert intro: le_infI2) lemma finite_lattice_complete_Inf_greatest: "\x::'a::finite_lattice_complete \ A. z \ x \ z \ Inf A" -unfolding Inf_def by (metis finite_code inf_le_fold_inf inf_top_right) + using finite [of A] by (induct A) (auto simp add: finite_lattice_complete_Inf_empty finite_lattice_complete_Inf_insert) lemma finite_lattice_complete_Sup_upper: "(x::'a::finite_lattice_complete) \ A \ Sup A \ x" -unfolding Sup_def by (metis finite_code le_sup_iff sup_le_fold_sup) + using finite [of A] by (induct A) (auto simp add: finite_lattice_complete_Sup_insert intro: le_supI2) lemma finite_lattice_complete_Sup_least: "\x::'a::finite_lattice_complete \ A. z \ x \ z \ Sup A" -unfolding Sup_def by (metis finite_code fold_sup_le_sup sup_bot_right) + using finite [of A] by (induct A) (auto simp add: finite_lattice_complete_Sup_empty finite_lattice_complete_Sup_insert) instance finite_lattice_complete \ complete_lattice proof diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Library/Formal_Power_Series.thy --- a/src/HOL/Library/Formal_Power_Series.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Library/Formal_Power_Series.thy Sat Mar 23 20:50:39 2013 +0100 @@ -1022,7 +1022,7 @@ also have "\ = (\i = 0..m. a ^ l $ i * a $ (m - i))" by (simp add: fps_mult_nth) also have "\ = 0" apply (rule setsum_0') apply auto - apply (case_tac "aa = m") + apply (case_tac "x = m") using a0 apply simp apply (rule H[rule_format]) @@ -2270,10 +2270,10 @@ unfolding fps_mult_nth apply (rule setsum_0') apply (clarsimp simp add: not_le) - apply (case_tac "aaa < aa") + apply (case_tac "x < aa") apply (rule startsby_zero_power_prefix[OF c0, rule_format]) apply simp - apply (subgoal_tac "n - aaa < ba") + apply (subgoal_tac "n - x < ba") apply (frule_tac k = "ba" in startsby_zero_power_prefix[OF d0, rule_format]) apply simp apply arith diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Library/Function_Algebras.thy --- a/src/HOL/Library/Function_Algebras.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Library/Function_Algebras.thy Sat Mar 23 20:50:39 2013 +0100 @@ -97,9 +97,6 @@ instance "fun" :: (type, ab_semigroup_mult) ab_semigroup_mult by default (simp add: fun_eq_iff mult.commute) -instance "fun" :: (type, ab_semigroup_idem_mult) ab_semigroup_idem_mult - by default (simp add: fun_eq_iff) - instance "fun" :: (type, monoid_mult) monoid_mult by default (simp_all add: fun_eq_iff) diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Library/Nat_Bijection.thy --- a/src/HOL/Library/Nat_Bijection.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Library/Nat_Bijection.thy Sat Mar 23 20:50:39 2013 +0100 @@ -377,7 +377,7 @@ by (metis finite_set_decode set_decode_inverse) thus ?thesis using assms apply auto - apply (simp add: set_encode_def nat_add_commute setsum.F_subset_diff) + apply (simp add: set_encode_def nat_add_commute setsum.subset_diff) done qed thus ?thesis @@ -385,3 +385,4 @@ qed end + diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Library/Permutations.thy --- a/src/HOL/Library/Permutations.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Library/Permutations.thy Sat Mar 23 20:50:39 2013 +0100 @@ -216,36 +216,36 @@ (* Permutations of index set for iterated operations. *) (* ------------------------------------------------------------------------- *) -lemma (in ab_semigroup_mult) fold_image_permute: assumes fS: "finite S" and pS: "p permutes S" - shows "fold_image times f z S = fold_image times (f o p) z S" - using fold_image_reindex[OF fS subset_inj_on[OF permutes_inj[OF pS], of S, simplified], of f z] - unfolding permutes_image[OF pS] . -lemma (in ab_semigroup_add) fold_image_permute: assumes fS: "finite S" and pS: "p permutes S" - shows "fold_image plus f z S = fold_image plus (f o p) z S" -proof- - interpret ab_semigroup_mult plus apply unfold_locales apply (simp add: add_assoc) - apply (simp add: add_commute) done - from fold_image_reindex[OF fS subset_inj_on[OF permutes_inj[OF pS], of S, simplified], of f z] - show ?thesis - unfolding permutes_image[OF pS] . +lemma (in comm_monoid_set) permute: + assumes "p permutes S" + shows "F g S = F (g o p) S" +proof - + from `p permutes S` have "inj p" by (rule permutes_inj) + then have "inj_on p S" by (auto intro: subset_inj_on) + then have "F g (p ` S) = F (g o p) S" by (rule reindex) + moreover from `p permutes S` have "p ` S = S" by (rule permutes_image) + ultimately show ?thesis by simp qed -lemma setsum_permute: assumes pS: "p permutes S" +lemma setsum_permute: + assumes "p permutes S" shows "setsum f S = setsum (f o p) S" - unfolding setsum_def using fold_image_permute[of S p f 0] pS by clarsimp + using assms by (fact setsum.permute) -lemma setsum_permute_natseg:assumes pS: "p permutes {m .. n}" +lemma setsum_permute_natseg: + assumes pS: "p permutes {m .. n}" shows "setsum f {m .. n} = setsum (f o p) {m .. n}" - using setsum_permute[OF pS, of f ] pS by blast + using setsum_permute [OF pS, of f ] pS by blast -lemma setprod_permute: assumes pS: "p permutes S" +lemma setprod_permute: + assumes "p permutes S" shows "setprod f S = setprod (f o p) S" - unfolding setprod_def - using ab_semigroup_mult_class.fold_image_permute[of S p f 1] pS by clarsimp + using assms by (fact setprod.permute) -lemma setprod_permute_natseg:assumes pS: "p permutes {m .. n}" +lemma setprod_permute_natseg: + assumes pS: "p permutes {m .. n}" shows "setprod f {m .. n} = setprod (f o p) {m .. n}" - using setprod_permute[OF pS, of f ] pS by blast + using setprod_permute [OF pS, of f ] pS by blast (* ------------------------------------------------------------------------- *) (* Various combinations of transpositions with 2, 1 and 0 common elements. *) @@ -835,7 +835,6 @@ by (simp add: o_def) with bc have "b = c \ p = q" by blast } - then show "inj_on ?f (insert a S \ ?P)" unfolding inj_on_def apply clarify by metis @@ -843,3 +842,4 @@ qed end + diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Library/RBT_Set.thy --- a/src/HOL/Library/RBT_Set.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Library/RBT_Set.thy Sat Mar 23 20:50:39 2013 +0100 @@ -316,11 +316,10 @@ assumes "is_rbt t" shows "rbt_min t = rbt_min_opt t" proof - - interpret ab_semigroup_idem_mult "(min :: 'a \ 'a \ 'a)" using ab_semigroup_idem_mult_min - unfolding class.ab_semigroup_idem_mult_def by blast - show ?thesis - by (simp add: Min_eqI rbt_min_opt_is_min rbt_min_opt_in_set assms Min_def[symmetric] - non_empty_rbt_keys fold1_set_fold[symmetric] rbt_min_def rbt_fold1_keys_def) + from assms have "hd (RBT_Impl.keys t) # tl (RBT_Impl.keys t) = RBT_Impl.keys t" by (cases t) simp_all + with assms show ?thesis + by (simp add: rbt_min_def rbt_fold1_keys_def rbt_min_opt_is_min + min_max.Inf_fin.set_eq_fold [symmetric] Min_eqI rbt_min_opt_in_set) qed (* maximum *) @@ -337,12 +336,7 @@ fixes xs :: "('a :: linorder) list" assumes "xs \ []" shows "List.fold max (tl xs) (hd xs) = List.fold max (tl (rev xs)) (hd (rev xs))" -proof - - interpret ab_semigroup_idem_mult "(max :: 'a \ 'a \ 'a)" using ab_semigroup_idem_mult_max - unfolding class.ab_semigroup_idem_mult_def by blast - show ?thesis - using assms by (auto simp add: fold1_set_fold[symmetric]) -qed + using assms by (simp add: min_max.Sup_fin.set_eq_fold [symmetric]) lemma rbt_max_simps: assumes "is_rbt (Branch c lt k v RBT_Impl.Empty)" @@ -416,11 +410,10 @@ assumes "is_rbt t" shows "rbt_max t = rbt_max_opt t" proof - - interpret ab_semigroup_idem_mult "(max :: 'a \ 'a \ 'a)" using ab_semigroup_idem_mult_max - unfolding class.ab_semigroup_idem_mult_def by blast - show ?thesis - by (simp add: Max_eqI rbt_max_opt_is_max rbt_max_opt_in_set assms Max_def[symmetric] - non_empty_rbt_keys fold1_set_fold[symmetric] rbt_max_def rbt_fold1_keys_def) + from assms have "hd (RBT_Impl.keys t) # tl (RBT_Impl.keys t) = RBT_Impl.keys t" by (cases t) simp_all + with assms show ?thesis + by (simp add: rbt_max_def rbt_fold1_keys_def rbt_max_opt_is_max + min_max.Sup_fin.set_eq_fold [symmetric] Max_eqI rbt_max_opt_in_set) qed @@ -434,13 +427,13 @@ by transfer (simp add: rbt_fold1_keys_def) lemma finite_fold1_fold1_keys: - assumes "class.ab_semigroup_mult f" - assumes "\ (is_empty t)" - shows "Finite_Set.fold1 f (Set t) = fold1_keys f t" + assumes "semilattice f" + assumes "\ is_empty t" + shows "semilattice_set.F f (Set t) = fold1_keys f t" proof - - interpret ab_semigroup_mult f by fact + from `semilattice f` interpret semilattice_set f by (rule semilattice_set.intro) show ?thesis using assms - by (auto simp: fold1_keys_def_alt set_keys fold_def_alt fold1_distinct_set_fold non_empty_keys) + by (auto simp: fold1_keys_def_alt set_keys fold_def_alt non_empty_keys set_eq_fold [symmetric]) qed (* minimum *) @@ -658,14 +651,14 @@ lemma card_Set [code]: "card (Set t) = fold_keys (\_ n. n + 1) t 0" -by (auto simp add: card_def fold_image_def intro!: finite_fold_fold_keys) (default, simp) + by (auto simp add: card.eq_fold intro: finite_fold_fold_keys comp_fun_commute_const) lemma setsum_Set [code]: "setsum f (Set xs) = fold_keys (plus o f) xs 0" proof - have "comp_fun_commute (\x. op + (f x))" by default (auto simp: add_ac) then show ?thesis - by (auto simp add: setsum_def fold_image_def finite_fold_fold_keys o_def) + by (auto simp add: setsum.eq_fold finite_fold_fold_keys o_def) qed definition not_a_singleton_tree where [code del]: "not_a_singleton_tree x y = x y" @@ -743,11 +736,10 @@ lemma Min_fin_set_fold [code]: "Min (Set t) = (if is_empty t then not_non_empty_tree Min (Set t) else r_min_opt t)" proof - - have *:"(class.ab_semigroup_mult (min :: 'a \ 'a \ 'a))" using ab_semigroup_idem_mult_min - unfolding class.ab_semigroup_idem_mult_def by blast + have *: "semilattice (min :: 'a \ 'a \ 'a)" .. + with finite_fold1_fold1_keys [OF *, folded Min_def] show ?thesis - by (auto simp add: Min_def not_non_empty_tree_def finite_fold1_fold1_keys[OF *] r_min_alt_def - r_min_eq_r_min_opt[symmetric]) + by (simp add: not_non_empty_tree_def r_min_alt_def r_min_eq_r_min_opt [symmetric]) qed lemma Inf_fin_set_fold [code]: @@ -781,11 +773,10 @@ lemma Max_fin_set_fold [code]: "Max (Set t) = (if is_empty t then not_non_empty_tree Max (Set t) else r_max_opt t)" proof - - have *:"(class.ab_semigroup_mult (max :: 'a \ 'a \ 'a))" using ab_semigroup_idem_mult_max - unfolding class.ab_semigroup_idem_mult_def by blast + have *: "semilattice (max :: 'a \ 'a \ 'a)" .. + with finite_fold1_fold1_keys [OF *, folded Max_def] show ?thesis - by (auto simp add: Max_def not_non_empty_tree_def finite_fold1_fold1_keys[OF *] r_max_alt_def - r_max_eq_r_max_opt[symmetric]) + by (simp add: not_non_empty_tree_def r_max_alt_def r_max_eq_r_max_opt [symmetric]) qed lemma Sup_fin_set_fold [code]: diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Library/Saturated.thy --- a/src/HOL/Library/Saturated.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Library/Saturated.thy Sat Mar 23 20:50:39 2013 +0100 @@ -207,47 +207,65 @@ end -instantiation sat :: (len) complete_lattice +instantiation sat :: (len) "{Inf, Sup}" begin definition - "Inf (A :: 'a sat set) = Finite_Set.fold min top A" + "Inf = (semilattice_neutr_set.F min top :: 'a sat set \ 'a sat)" definition - "Sup (A :: 'a sat set) = Finite_Set.fold max bot A" + "Sup = (semilattice_neutr_set.F max bot :: 'a sat set \ 'a sat)" + +instance .. + +end -instance proof +interpretation Inf_sat!: semilattice_neutr_set min "top :: 'a::len sat" +where + "semilattice_neutr_set.F min (top :: 'a sat) = Inf" +proof - + show "semilattice_neutr_set min (top :: 'a sat)" by default (simp add: min_def) + show "semilattice_neutr_set.F min (top :: 'a sat) = Inf" by (simp add: Inf_sat_def) +qed + +interpretation Sup_sat!: semilattice_neutr_set max "bot :: 'a::len sat" +where + "semilattice_neutr_set.F max (bot :: 'a sat) = Sup" +proof - + show "semilattice_neutr_set max (bot :: 'a sat)" by default (simp add: max_def bot.extremum_unique) + show "semilattice_neutr_set.F max (bot :: 'a sat) = Sup" by (simp add: Sup_sat_def) +qed + +instance sat :: (len) complete_lattice +proof fix x :: "'a sat" fix A :: "'a sat set" note finite moreover assume "x \ A" - ultimately have "Finite_Set.fold min top A \ min x top" by (rule min_max.fold_inf_le_inf) - then show "Inf A \ x" by (simp add: Inf_sat_def) + ultimately show "Inf A \ x" + by (induct A) (auto intro: min_max.le_infI2) next fix z :: "'a sat" fix A :: "'a sat set" note finite moreover assume z: "\x. x \ A \ z \ x" - ultimately have "min z top \ Finite_Set.fold min top A" by (blast intro: min_max.inf_le_fold_inf) - then show "z \ Inf A" by (simp add: Inf_sat_def min_def) + ultimately show "z \ Inf A" by (induct A) simp_all next fix x :: "'a sat" fix A :: "'a sat set" note finite moreover assume "x \ A" - ultimately have "max x bot \ Finite_Set.fold max bot A" by (rule min_max.sup_le_fold_sup) - then show "x \ Sup A" by (simp add: Sup_sat_def) + ultimately show "x \ Sup A" + by (induct A) (auto intro: min_max.le_supI2) next fix z :: "'a sat" fix A :: "'a sat set" note finite moreover assume z: "\x. x \ A \ x \ z" - ultimately have "Finite_Set.fold max bot A \ max z bot" by (blast intro: min_max.fold_sup_le_sup) - then show "Sup A \ z" by (simp add: Sup_sat_def max_def bot_unique) + ultimately show "Sup A \ z" by (induct A) auto qed -end - hide_const (open) sat_of_nat end + diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/List.thy --- a/src/HOL/List.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/List.thy Sat Mar 23 20:50:39 2013 +0100 @@ -2734,51 +2734,11 @@ lemma (in comp_fun_commute) fold_set_fold_remdups: "Finite_Set.fold f y (set xs) = fold f (remdups xs) y" - by (rule sym, induct xs arbitrary: y) (simp_all add: fold_fun_comm insert_absorb) - -lemma (in ab_semigroup_mult) fold1_distinct_set_fold: - assumes "xs \ []" - assumes d: "distinct xs" - shows "Finite_Set.fold1 times (set xs) = List.fold times (tl xs) (hd xs)" -proof - - interpret comp_fun_commute times by (fact comp_fun_commute) - from assms obtain y ys where xs: "xs = y # ys" - by (cases xs) auto - then have *: "y \ set ys" using assms by simp - from xs d have **: "remdups ys = ys" by safe (induct ys, auto) - show ?thesis - proof (cases "set ys = {}") - case True with xs show ?thesis by simp - next - case False - then have "fold1 times (Set.insert y (set ys)) = Finite_Set.fold times y (set ys)" - by (simp_all add: fold1_eq_fold *) - with xs show ?thesis - by (simp add: fold_set_fold_remdups **) - qed -qed + by (rule sym, induct xs arbitrary: y) (simp_all add: fold_fun_left_comm insert_absorb) lemma (in comp_fun_idem) fold_set_fold: "Finite_Set.fold f y (set xs) = fold f xs y" - by (rule sym, induct xs arbitrary: y) (simp_all add: fold_fun_comm) - -lemma (in ab_semigroup_idem_mult) fold1_set_fold: - assumes "xs \ []" - shows "Finite_Set.fold1 times (set xs) = fold times (tl xs) (hd xs)" -proof - - interpret comp_fun_idem times by (fact comp_fun_idem) - from assms obtain y ys where xs: "xs = y # ys" - by (cases xs) auto - show ?thesis - proof (cases "set ys = {}") - case True with xs show ?thesis by simp - next - case False - then have "fold1 times (insert y (set ys)) = Finite_Set.fold times y (set ys)" - by (simp only: finite_set fold1_eq_fold_idem) - with xs show ?thesis by (simp add: fold_set_fold mult_commute) - qed -qed + by (rule sym, induct xs arbitrary: y) (simp_all add: fold_fun_left_comm) lemma union_set_fold [code]: "set xs \ A = fold Set.insert xs A" @@ -2813,49 +2773,18 @@ "A \ List.coset xs = fold Set.remove xs A" by (simp add: Diff_eq [symmetric] minus_set_fold) -lemma (in lattice) Inf_fin_set_fold: - "Inf_fin (set (x # xs)) = fold inf xs x" +lemma (in semilattice_set) set_eq_fold: + "F (set (x # xs)) = fold f xs x" proof - - interpret ab_semigroup_idem_mult "inf :: 'a \ 'a \ 'a" - by (fact ab_semigroup_idem_mult_inf) - show ?thesis - by (simp add: Inf_fin_def fold1_set_fold del: set.simps) -qed - -declare Inf_fin_set_fold [code] - -lemma (in lattice) Sup_fin_set_fold: - "Sup_fin (set (x # xs)) = fold sup xs x" -proof - - interpret ab_semigroup_idem_mult "sup :: 'a \ 'a \ 'a" - by (fact ab_semigroup_idem_mult_sup) - show ?thesis - by (simp add: Sup_fin_def fold1_set_fold del: set.simps) + interpret comp_fun_idem f + by default (simp_all add: fun_eq_iff left_commute) + show ?thesis by (simp add: eq_fold fold_set_fold) qed -declare Sup_fin_set_fold [code] - -lemma (in linorder) Min_fin_set_fold: - "Min (set (x # xs)) = fold min xs x" -proof - - interpret ab_semigroup_idem_mult "min :: 'a \ 'a \ 'a" - by (fact ab_semigroup_idem_mult_min) - show ?thesis - by (simp add: Min_def fold1_set_fold del: set.simps) -qed - -declare Min_fin_set_fold [code] - -lemma (in linorder) Max_fin_set_fold: - "Max (set (x # xs)) = fold max xs x" -proof - - interpret ab_semigroup_idem_mult "max :: 'a \ 'a \ 'a" - by (fact ab_semigroup_idem_mult_max) - show ?thesis - by (simp add: Max_def fold1_set_fold del: set.simps) -qed - -declare Max_fin_set_fold [code] +declare Inf_fin.set_eq_fold [code] +declare Sup_fin.set_eq_fold [code] +declare min_max.Inf_fin.set_eq_fold [code] +declare min_max.Sup_fin.set_eq_fold [code] lemma (in complete_lattice) Inf_set_fold: "Inf (set xs) = fold inf xs top" @@ -4915,24 +4844,36 @@ sets to lists but one should convert in the other direction (via @{const set}). *} +subsubsection {* @{text sorted_list_of_set} *} + +text{* This function maps (finite) linearly ordered sets to sorted +lists. Warning: in most cases it is not a good idea to convert from +sets to lists but one should convert in the other direction (via +@{const set}). *} + +definition (in linorder) sorted_list_of_set :: "'a set \ 'a list" where + "sorted_list_of_set = folding.F insort []" + +sublocale linorder < sorted_list_of_set!: folding insort Nil +where + "folding.F insort [] = sorted_list_of_set" +proof - + interpret comp_fun_commute insort by (fact comp_fun_commute_insort) + show "folding insort" by default (fact comp_fun_commute) + show "folding.F insort [] = sorted_list_of_set" by (simp only: sorted_list_of_set_def) +qed + context linorder begin -definition sorted_list_of_set :: "'a set \ 'a list" where -"sorted_list_of_set = Finite_Set.fold insort []" - -lemma sorted_list_of_set_empty [simp]: +lemma sorted_list_of_set_empty: "sorted_list_of_set {} = []" - by (simp add: sorted_list_of_set_def) + by (fact sorted_list_of_set.empty) lemma sorted_list_of_set_insert [simp]: assumes "finite A" shows "sorted_list_of_set (insert x A) = insort x (sorted_list_of_set (A - {x}))" -proof - - interpret comp_fun_commute insort by (fact comp_fun_commute_insort) - from assms show ?thesis - by (simp add: sorted_list_of_set_def fold_insert_remove) -qed + using assms by (fact sorted_list_of_set.insert_remove) lemma sorted_list_of_set [simp]: "finite A \ set (sorted_list_of_set A) = A \ sorted (sorted_list_of_set A) @@ -4943,7 +4884,7 @@ "sorted_list_of_set (set xs) = sort (remdups xs)" proof - interpret comp_fun_commute insort by (fact comp_fun_commute_insort) - show ?thesis by (simp add: sorted_list_of_set_def sort_conv_fold fold_set_fold_remdups) + show ?thesis by (simp add: sorted_list_of_set.eq_fold sort_conv_fold fold_set_fold_remdups) qed lemma sorted_list_of_set_remove: diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/MacLaurin.thy --- a/src/HOL/MacLaurin.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/MacLaurin.thy Sat Mar 23 20:50:39 2013 +0100 @@ -428,7 +428,7 @@ apply (simp (no_asm)) apply (simp (no_asm) add: sin_expansion_lemma) apply (force intro!: DERIV_intros) -apply (subst (asm) setsum_0', clarify, case_tac "a", simp, simp) +apply (subst (asm) setsum_0', clarify, case_tac "x", simp, simp) apply (cases n, simp, simp) apply (rule ccontr, simp) apply (drule_tac x = x in spec, simp) diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Multivariate_Analysis/Cartesian_Euclidean_Space.thy --- a/src/HOL/Multivariate_Analysis/Cartesian_Euclidean_Space.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Multivariate_Analysis/Cartesian_Euclidean_Space.thy Sat Mar 23 20:50:39 2013 +0100 @@ -188,9 +188,6 @@ instance vec :: (ab_semigroup_mult, finite) ab_semigroup_mult by default (vector mult_commute) -instance vec :: (ab_semigroup_idem_mult, finite) ab_semigroup_idem_mult - by default (vector mult_idem) - instance vec :: (comm_monoid_mult, finite) comm_monoid_mult by default vector diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Multivariate_Analysis/Determinants.thy --- a/src/HOL/Multivariate_Analysis/Determinants.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Multivariate_Analysis/Determinants.thy Sat Mar 23 20:50:39 2013 +0100 @@ -103,18 +103,7 @@ lemma setprod_permute: assumes p: "p permutes S" shows "setprod f S = setprod (f o p) S" -proof- - {assume "\ finite S" hence ?thesis by simp} - moreover - {assume fS: "finite S" - then have ?thesis - apply (simp add: setprod_def cong del:strong_setprod_cong) - apply (rule ab_semigroup_mult.fold_image_permute) - apply (auto simp add: p) - apply unfold_locales - done} - ultimately show ?thesis by blast -qed + using assms by (fact setprod.permute) lemma setproduct_permute_nat_interval: "p permutes {m::nat .. n} ==> setprod f {m..n} = setprod (f o p) {m..n}" by (blast intro!: setprod_permute) diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Multivariate_Analysis/Integration.thy --- a/src/HOL/Multivariate_Analysis/Integration.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Multivariate_Analysis/Integration.thy Sat Mar 23 20:50:39 2013 +0100 @@ -2744,12 +2744,15 @@ subsection {* Additivity of content. *} -lemma setsum_iterate:assumes "finite s" shows "setsum f s = iterate op + s f" -proof- have *:"setsum f s = setsum f (support op + f s)" - apply(rule setsum_mono_zero_right) +lemma setsum_iterate: + assumes "finite s" shows "setsum f s = iterate op + s f" +proof - + have *: "setsum f s = setsum f (support op + f s)" + apply (rule setsum_mono_zero_right) unfolding support_def neutral_monoid using assms by auto - thus ?thesis unfolding * setsum_def iterate_def fold_image_def fold'_def - unfolding neutral_monoid . qed + then show ?thesis unfolding * iterate_def fold'_def setsum.eq_fold + unfolding neutral_monoid by (simp add: comp_def) +qed lemma additive_content_division: assumes "d division_of {a..b}" shows "setsum content d = content({a..b})" diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Number_Theory/UniqueFactorization.thy --- a/src/HOL/Number_Theory/UniqueFactorization.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Number_Theory/UniqueFactorization.thy Sat Mar 23 20:50:39 2013 +0100 @@ -36,36 +36,71 @@ "ALL i :# M. P i"? *) +no_notation times (infixl "*" 70) +no_notation Groups.one ("1") + +locale comm_monoid_mset = comm_monoid +begin + +definition F :: "'a multiset \ 'a" +where + eq_fold: "F M = Multiset.fold f 1 M" + +lemma empty [simp]: + "F {#} = 1" + by (simp add: eq_fold) + +lemma singleton [simp]: + "F {#x#} = x" +proof - + interpret comp_fun_commute + by default (simp add: fun_eq_iff left_commute) + show ?thesis by (simp add: eq_fold) +qed + +lemma union [simp]: + "F (M + N) = F M * F N" +proof - + interpret comp_fun_commute f + by default (simp add: fun_eq_iff left_commute) + show ?thesis by (induct N) (simp_all add: left_commute eq_fold) +qed + +end + +notation times (infixl "*" 70) +notation Groups.one ("1") + +definition (in comm_monoid_mult) msetprod :: "'a multiset \ 'a" +where + "msetprod = comm_monoid_mset.F times 1" + +sublocale comm_monoid_mult < msetprod!: comm_monoid_mset times 1 +where + "comm_monoid_mset.F times 1 = msetprod" +proof - + show "comm_monoid_mset times 1" .. + from msetprod_def show "comm_monoid_mset.F times 1 = msetprod" by rule +qed + context comm_monoid_mult begin -definition msetprod :: "'a multiset \ 'a" -where - "msetprod M = Multiset.fold times 1 M" +lemma msetprod_empty: + "msetprod {#} = 1" + by (fact msetprod.empty) -lemma msetprod_empty [simp]: - "msetprod {#} = 1" - by (simp add: msetprod_def) - -lemma msetprod_singleton [simp]: +lemma msetprod_singleton: "msetprod {#x#} = x" -proof - - interpret comp_fun_commute times - by (fact comp_fun_commute) - show ?thesis by (simp add: msetprod_def) -qed + by (fact msetprod.singleton) -lemma msetprod_Un [simp]: +lemma msetprod_Un: "msetprod (A + B) = msetprod A * msetprod B" -proof - - interpret comp_fun_commute times - by (fact comp_fun_commute) - show ?thesis by (induct B) (simp_all add: msetprod_def mult_ac) -qed + by (fact msetprod.union) lemma msetprod_multiplicity: "msetprod M = setprod (\x. x ^ count M x) (set_of M)" - by (simp add: msetprod_def setprod_def Multiset.fold_def fold_image_def funpow_times_power) + by (simp add: Multiset.fold_def setprod.eq_fold msetprod.eq_fold funpow_times_power comp_def) abbreviation msetprod_image :: "('b \ 'a) \ 'b multiset \ 'a" where @@ -111,8 +146,7 @@ by arith moreover { assume "n = 1" - then have "(ALL p : set_of {#}. prime p) & n = (PROD i :# {#}. i)" - by (auto simp add: msetprod_def) + then have "(ALL p : set_of {#}. prime p) & n = (PROD i :# {#}. i)" by auto } moreover { assume "n > 1" and "prime n" then have "(ALL p : set_of {# n #}. prime p) & n = (PROD i :# {# n #}. i)" diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Old_Number_Theory/Finite2.thy --- a/src/HOL/Old_Number_Theory/Finite2.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Old_Number_Theory/Finite2.thy Sat Mar 23 20:50:39 2013 +0100 @@ -23,7 +23,7 @@ assume "finite S" thus ?thesis using a by induct (simp_all add: zcong_zadd) next - assume "infinite S" thus ?thesis by(simp add:setsum_def) + assume "infinite S" thus ?thesis by simp qed lemma setprod_same_function_zcong: @@ -33,7 +33,7 @@ assume "finite S" thus ?thesis using a by induct (simp_all add: zcong_zmult) next - assume "infinite S" thus ?thesis by(simp add:setprod_def) + assume "infinite S" thus ?thesis by simp qed lemma setsum_const: "finite X ==> setsum (%x. (c :: int)) X = c * int(card X)" diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Old_Number_Theory/Pocklington.thy --- a/src/HOL/Old_Number_Theory/Pocklington.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Old_Number_Theory/Pocklington.thy Sat Mar 23 20:50:39 2013 +0100 @@ -566,7 +566,7 @@ [x1 = x2] (mod n) \ [y1 = y2] (mod n) \ [x1 * y1 = x2 * y2] (mod n)" by blast have th4:"\x\S. [a x mod n = a x] (mod n)" by (simp add: modeq_def) - from fold_image_related[where h="(\m. a(m) mod n)" and g=a, OF th1 th3 fS, OF th4] show ?thesis unfolding setprod_def by (simp add: fS) + from setprod.related [where h="(\m. a(m) mod n)" and g=a, OF th1 th3 fS, OF th4] show ?thesis by (simp add: fS) qed lemma nproduct_cmul: @@ -577,7 +577,7 @@ lemma coprime_nproduct: assumes fS: "finite S" and Sn: "\x\S. coprime n (a x)" shows "coprime n (setprod a S)" - using fS unfolding setprod_def by (rule finite_subset_induct) + using fS by (rule finite_subset_induct) (insert Sn, auto simp add: coprime_mul) lemma fermat_little: assumes an: "coprime a n" @@ -607,12 +607,8 @@ hence hS: "?h ` ?S = ?S"by (auto simp add: image_iff) have "a\0" using an n1 nz apply- apply (rule ccontr) by simp hence inj: "inj_on (op * a) ?S" unfolding inj_on_def by simp - - have eq0: "fold_image op * (?h \ op * a) 1 {m. coprime m n \ m < n} = - fold_image op * (\m. m) 1 {m. coprime m n \ m < n}" - proof (rule fold_image_eq_general[where h="?h o (op * a)"]) - show "finite ?S" using fS . - next + have eq0: "setprod (?h \ op * a) {m. coprime m n \ m < n} = setprod (\m. m) {m. coprime m n \ m < n}" + proof (rule setprod.eq_general [where h="?h o (op * a)"]) {fix y assume yS: "y \ ?S" hence y: "coprime y n" "y < n" by simp_all from cong_solve_unique[OF an nz, of y] obtain x where x:"x < n" "[a * x = y] (mod n)" "\z. z < n \ [a * z = y] (mod n) \ z=x" by blast diff -r 3c886fe611b8 -r f738e6dbd844 src/HOL/Probability/Fin_Map.thy --- a/src/HOL/Probability/Fin_Map.thy Sat Mar 23 17:11:06 2013 +0100 +++ b/src/HOL/Probability/Fin_Map.thy Sat Mar 23 20:50:39 2013 +0100 @@ -406,7 +406,7 @@ next fix P Q::"'a \\<^isub>F 'b" have Max_eq_iff: "\A m. finite A \ A \ {} \ (Max A = m) = (m \ A \ (\a\A. a \ m))" - by (metis Max.in_idem Max_in max_def min_max.sup.commute order_refl) + by (auto intro: Max_in Max_eqI) show "dist P Q = 0 \ P = Q" by (auto simp: finmap_eq_iff dist_finmap_def Max_ge_iff finite_proj_diag Max_eq_iff intro!: Max_eqI image_eqI[where x=undefined])