src/HOL/Finite_Set.thy
author huffman
Wed, 01 Apr 2009 11:34:21 -0700
changeset 30842 d007dee0c372
parent 30841 0813afc97522
parent 30837 3d4832d9f7e4
child 30844 7d0e10a961a6
permissions -rw-r--r--
merged
     1 (*  Title:      HOL/Finite_Set.thy
     2     Author:     Tobias Nipkow, Lawrence C Paulson and Markus Wenzel
     3                 with contributions by Jeremy Avigad
     4 *)
     5 
     6 header {* Finite sets *}
     7 
     8 theory Finite_Set
     9 imports Nat Product_Type Power
    10 begin
    11 
    12 subsection {* Definition and basic properties *}
    13 
    14 inductive finite :: "'a set => bool"
    15   where
    16     emptyI [simp, intro!]: "finite {}"
    17   | insertI [simp, intro!]: "finite A ==> finite (insert a A)"
    18 
    19 lemma ex_new_if_finite: -- "does not depend on def of finite at all"
    20   assumes "\<not> finite (UNIV :: 'a set)" and "finite A"
    21   shows "\<exists>a::'a. a \<notin> A"
    22 proof -
    23   from assms have "A \<noteq> UNIV" by blast
    24   thus ?thesis by blast
    25 qed
    26 
    27 lemma finite_induct [case_names empty insert, induct set: finite]:
    28   "finite F ==>
    29     P {} ==> (!!x F. finite F ==> x \<notin> F ==> P F ==> P (insert x F)) ==> P F"
    30   -- {* Discharging @{text "x \<notin> F"} entails extra work. *}
    31 proof -
    32   assume "P {}" and
    33     insert: "!!x F. finite F ==> x \<notin> F ==> P F ==> P (insert x F)"
    34   assume "finite F"
    35   thus "P F"
    36   proof induct
    37     show "P {}" by fact
    38     fix x F assume F: "finite F" and P: "P F"
    39     show "P (insert x F)"
    40     proof cases
    41       assume "x \<in> F"
    42       hence "insert x F = F" by (rule insert_absorb)
    43       with P show ?thesis by (simp only:)
    44     next
    45       assume "x \<notin> F"
    46       from F this P show ?thesis by (rule insert)
    47     qed
    48   qed
    49 qed
    50 
    51 lemma finite_ne_induct[case_names singleton insert, consumes 2]:
    52 assumes fin: "finite F" shows "F \<noteq> {} \<Longrightarrow>
    53  \<lbrakk> \<And>x. P{x};
    54    \<And>x F. \<lbrakk> finite F; F \<noteq> {}; x \<notin> F; P F \<rbrakk> \<Longrightarrow> P (insert x F) \<rbrakk>
    55  \<Longrightarrow> P F"
    56 using fin
    57 proof induct
    58   case empty thus ?case by simp
    59 next
    60   case (insert x F)
    61   show ?case
    62   proof cases
    63     assume "F = {}"
    64     thus ?thesis using `P {x}` by simp
    65   next
    66     assume "F \<noteq> {}"
    67     thus ?thesis using insert by blast
    68   qed
    69 qed
    70 
    71 lemma finite_subset_induct [consumes 2, case_names empty insert]:
    72   assumes "finite F" and "F \<subseteq> A"
    73     and empty: "P {}"
    74     and insert: "!!a F. finite F ==> a \<in> A ==> a \<notin> F ==> P F ==> P (insert a F)"
    75   shows "P F"
    76 proof -
    77   from `finite F` and `F \<subseteq> A`
    78   show ?thesis
    79   proof induct
    80     show "P {}" by fact
    81   next
    82     fix x F
    83     assume "finite F" and "x \<notin> F" and
    84       P: "F \<subseteq> A ==> P F" and i: "insert x F \<subseteq> A"
    85     show "P (insert x F)"
    86     proof (rule insert)
    87       from i show "x \<in> A" by blast
    88       from i have "F \<subseteq> A" by blast
    89       with P show "P F" .
    90       show "finite F" by fact
    91       show "x \<notin> F" by fact
    92     qed
    93   qed
    94 qed
    95 
    96 text{* A finite choice principle. Does not need the SOME choice operator. *}
    97 lemma finite_set_choice:
    98   "finite A \<Longrightarrow> ALL x:A. (EX y. P x y) \<Longrightarrow> EX f. ALL x:A. P x (f x)"
    99 proof (induct set: finite)
   100   case empty thus ?case by simp
   101 next
   102   case (insert a A)
   103   then obtain f b where f: "ALL x:A. P x (f x)" and ab: "P a b" by auto
   104   show ?case (is "EX f. ?P f")
   105   proof
   106     show "?P(%x. if x = a then b else f x)" using f ab by auto
   107   qed
   108 qed
   109 
   110 
   111 text{* Finite sets are the images of initial segments of natural numbers: *}
   112 
   113 lemma finite_imp_nat_seg_image_inj_on:
   114   assumes fin: "finite A" 
   115   shows "\<exists> (n::nat) f. A = f ` {i. i<n} & inj_on f {i. i<n}"
   116 using fin
   117 proof induct
   118   case empty
   119   show ?case  
   120   proof show "\<exists>f. {} = f ` {i::nat. i < 0} & inj_on f {i. i<0}" by simp 
   121   qed
   122 next
   123   case (insert a A)
   124   have notinA: "a \<notin> A" by fact
   125   from insert.hyps obtain n f
   126     where "A = f ` {i::nat. i < n}" "inj_on f {i. i < n}" by blast
   127   hence "insert a A = f(n:=a) ` {i. i < Suc n}"
   128         "inj_on (f(n:=a)) {i. i < Suc n}" using notinA
   129     by (auto simp add: image_def Ball_def inj_on_def less_Suc_eq)
   130   thus ?case by blast
   131 qed
   132 
   133 lemma nat_seg_image_imp_finite:
   134   "!!f A. A = f ` {i::nat. i<n} \<Longrightarrow> finite A"
   135 proof (induct n)
   136   case 0 thus ?case by simp
   137 next
   138   case (Suc n)
   139   let ?B = "f ` {i. i < n}"
   140   have finB: "finite ?B" by(rule Suc.hyps[OF refl])
   141   show ?case
   142   proof cases
   143     assume "\<exists>k<n. f n = f k"
   144     hence "A = ?B" using Suc.prems by(auto simp:less_Suc_eq)
   145     thus ?thesis using finB by simp
   146   next
   147     assume "\<not>(\<exists> k<n. f n = f k)"
   148     hence "A = insert (f n) ?B" using Suc.prems by(auto simp:less_Suc_eq)
   149     thus ?thesis using finB by simp
   150   qed
   151 qed
   152 
   153 lemma finite_conv_nat_seg_image:
   154   "finite A = (\<exists> (n::nat) f. A = f ` {i::nat. i<n})"
   155 by(blast intro: nat_seg_image_imp_finite dest: finite_imp_nat_seg_image_inj_on)
   156 
   157 lemma finite_Collect_less_nat[iff]: "finite{n::nat. n<k}"
   158 by(fastsimp simp: finite_conv_nat_seg_image)
   159 
   160 
   161 subsubsection{* Finiteness and set theoretic constructions *}
   162 
   163 lemma finite_UnI: "finite F ==> finite G ==> finite (F Un G)"
   164 by (induct set: finite) simp_all
   165 
   166 lemma finite_subset: "A \<subseteq> B ==> finite B ==> finite A"
   167   -- {* Every subset of a finite set is finite. *}
   168 proof -
   169   assume "finite B"
   170   thus "!!A. A \<subseteq> B ==> finite A"
   171   proof induct
   172     case empty
   173     thus ?case by simp
   174   next
   175     case (insert x F A)
   176     have A: "A \<subseteq> insert x F" and r: "A - {x} \<subseteq> F ==> finite (A - {x})" by fact+
   177     show "finite A"
   178     proof cases
   179       assume x: "x \<in> A"
   180       with A have "A - {x} \<subseteq> F" by (simp add: subset_insert_iff)
   181       with r have "finite (A - {x})" .
   182       hence "finite (insert x (A - {x}))" ..
   183       also have "insert x (A - {x}) = A" using x by (rule insert_Diff)
   184       finally show ?thesis .
   185     next
   186       show "A \<subseteq> F ==> ?thesis" by fact
   187       assume "x \<notin> A"
   188       with A show "A \<subseteq> F" by (simp add: subset_insert_iff)
   189     qed
   190   qed
   191 qed
   192 
   193 lemma finite_Un [iff]: "finite (F Un G) = (finite F & finite G)"
   194 by (blast intro: finite_subset [of _ "X Un Y", standard] finite_UnI)
   195 
   196 lemma finite_Collect_disjI[simp]:
   197   "finite{x. P x | Q x} = (finite{x. P x} & finite{x. Q x})"
   198 by(simp add:Collect_disj_eq)
   199 
   200 lemma finite_Int [simp, intro]: "finite F | finite G ==> finite (F Int G)"
   201   -- {* The converse obviously fails. *}
   202 by (blast intro: finite_subset)
   203 
   204 lemma finite_Collect_conjI [simp, intro]:
   205   "finite{x. P x} | finite{x. Q x} ==> finite{x. P x & Q x}"
   206   -- {* The converse obviously fails. *}
   207 by(simp add:Collect_conj_eq)
   208 
   209 lemma finite_Collect_le_nat[iff]: "finite{n::nat. n<=k}"
   210 by(simp add: le_eq_less_or_eq)
   211 
   212 lemma finite_insert [simp]: "finite (insert a A) = finite A"
   213   apply (subst insert_is_Un)
   214   apply (simp only: finite_Un, blast)
   215   done
   216 
   217 lemma finite_Union[simp, intro]:
   218  "\<lbrakk> finite A; !!M. M \<in> A \<Longrightarrow> finite M \<rbrakk> \<Longrightarrow> finite(\<Union>A)"
   219 by (induct rule:finite_induct) simp_all
   220 
   221 lemma finite_empty_induct:
   222   assumes "finite A"
   223     and "P A"
   224     and "!!a A. finite A ==> a:A ==> P A ==> P (A - {a})"
   225   shows "P {}"
   226 proof -
   227   have "P (A - A)"
   228   proof -
   229     {
   230       fix c b :: "'a set"
   231       assume c: "finite c" and b: "finite b"
   232 	and P1: "P b" and P2: "!!x y. finite y ==> x \<in> y ==> P y ==> P (y - {x})"
   233       have "c \<subseteq> b ==> P (b - c)"
   234 	using c
   235       proof induct
   236 	case empty
   237 	from P1 show ?case by simp
   238       next
   239 	case (insert x F)
   240 	have "P (b - F - {x})"
   241 	proof (rule P2)
   242           from _ b show "finite (b - F)" by (rule finite_subset) blast
   243           from insert show "x \<in> b - F" by simp
   244           from insert show "P (b - F)" by simp
   245 	qed
   246 	also have "b - F - {x} = b - insert x F" by (rule Diff_insert [symmetric])
   247 	finally show ?case .
   248       qed
   249     }
   250     then show ?thesis by this (simp_all add: assms)
   251   qed
   252   then show ?thesis by simp
   253 qed
   254 
   255 lemma finite_Diff [simp]: "finite A ==> finite (A - B)"
   256 by (rule Diff_subset [THEN finite_subset])
   257 
   258 lemma finite_Diff2 [simp]:
   259   assumes "finite B" shows "finite (A - B) = finite A"
   260 proof -
   261   have "finite A \<longleftrightarrow> finite((A-B) Un (A Int B))" by(simp add: Un_Diff_Int)
   262   also have "\<dots> \<longleftrightarrow> finite(A-B)" using `finite B` by(simp)
   263   finally show ?thesis ..
   264 qed
   265 
   266 lemma finite_compl[simp]:
   267   "finite(A::'a set) \<Longrightarrow> finite(-A) = finite(UNIV::'a set)"
   268 by(simp add:Compl_eq_Diff_UNIV)
   269 
   270 lemma finite_Collect_not[simp]:
   271   "finite{x::'a. P x} \<Longrightarrow> finite{x. ~P x} = finite(UNIV::'a set)"
   272 by(simp add:Collect_neg_eq)
   273 
   274 lemma finite_Diff_insert [iff]: "finite (A - insert a B) = finite (A - B)"
   275   apply (subst Diff_insert)
   276   apply (case_tac "a : A - B")
   277    apply (rule finite_insert [symmetric, THEN trans])
   278    apply (subst insert_Diff, simp_all)
   279   done
   280 
   281 
   282 text {* Image and Inverse Image over Finite Sets *}
   283 
   284 lemma finite_imageI[simp]: "finite F ==> finite (h ` F)"
   285   -- {* The image of a finite set is finite. *}
   286   by (induct set: finite) simp_all
   287 
   288 lemma finite_surj: "finite A ==> B <= f ` A ==> finite B"
   289   apply (frule finite_imageI)
   290   apply (erule finite_subset, assumption)
   291   done
   292 
   293 lemma finite_range_imageI:
   294     "finite (range g) ==> finite (range (%x. f (g x)))"
   295   apply (drule finite_imageI, simp add: range_composition)
   296   done
   297 
   298 lemma finite_imageD: "finite (f`A) ==> inj_on f A ==> finite A"
   299 proof -
   300   have aux: "!!A. finite (A - {}) = finite A" by simp
   301   fix B :: "'a set"
   302   assume "finite B"
   303   thus "!!A. f`A = B ==> inj_on f A ==> finite A"
   304     apply induct
   305      apply simp
   306     apply (subgoal_tac "EX y:A. f y = x & F = f ` (A - {y})")
   307      apply clarify
   308      apply (simp (no_asm_use) add: inj_on_def)
   309      apply (blast dest!: aux [THEN iffD1], atomize)
   310     apply (erule_tac V = "ALL A. ?PP (A)" in thin_rl)
   311     apply (frule subsetD [OF equalityD2 insertI1], clarify)
   312     apply (rule_tac x = xa in bexI)
   313      apply (simp_all add: inj_on_image_set_diff)
   314     done
   315 qed (rule refl)
   316 
   317 
   318 lemma inj_vimage_singleton: "inj f ==> f-`{a} \<subseteq> {THE x. f x = a}"
   319   -- {* The inverse image of a singleton under an injective function
   320          is included in a singleton. *}
   321   apply (auto simp add: inj_on_def)
   322   apply (blast intro: the_equality [symmetric])
   323   done
   324 
   325 lemma finite_vimageI: "[|finite F; inj h|] ==> finite (h -` F)"
   326   -- {* The inverse image of a finite set under an injective function
   327          is finite. *}
   328   apply (induct set: finite)
   329    apply simp_all
   330   apply (subst vimage_insert)
   331   apply (simp add: finite_Un finite_subset [OF inj_vimage_singleton])
   332   done
   333 
   334 
   335 text {* The finite UNION of finite sets *}
   336 
   337 lemma finite_UN_I: "finite A ==> (!!a. a:A ==> finite (B a)) ==> finite (UN a:A. B a)"
   338   by (induct set: finite) simp_all
   339 
   340 text {*
   341   Strengthen RHS to
   342   @{prop "((ALL x:A. finite (B x)) & finite {x. x:A & B x \<noteq> {}})"}?
   343 
   344   We'd need to prove
   345   @{prop "finite C ==> ALL A B. (UNION A B) <= C --> finite {x. x:A & B x \<noteq> {}}"}
   346   by induction. *}
   347 
   348 lemma finite_UN [simp]:
   349   "finite A ==> finite (UNION A B) = (ALL x:A. finite (B x))"
   350 by (blast intro: finite_UN_I finite_subset)
   351 
   352 lemma finite_Collect_bex[simp]: "finite A \<Longrightarrow>
   353   finite{x. EX y:A. Q x y} = (ALL y:A. finite{x. Q x y})"
   354 apply(subgoal_tac "{x. EX y:A. Q x y} = UNION A (%y. {x. Q x y})")
   355  apply auto
   356 done
   357 
   358 lemma finite_Collect_bounded_ex[simp]: "finite{y. P y} \<Longrightarrow>
   359   finite{x. EX y. P y & Q x y} = (ALL y. P y \<longrightarrow> finite{x. Q x y})"
   360 apply(subgoal_tac "{x. EX y. P y & Q x y} = UNION {y. P y} (%y. {x. Q x y})")
   361  apply auto
   362 done
   363 
   364 
   365 lemma finite_Plus: "[| finite A; finite B |] ==> finite (A <+> B)"
   366 by (simp add: Plus_def)
   367 
   368 text {* Sigma of finite sets *}
   369 
   370 lemma finite_SigmaI [simp]:
   371     "finite A ==> (!!a. a:A ==> finite (B a)) ==> finite (SIGMA a:A. B a)"
   372   by (unfold Sigma_def) (blast intro!: finite_UN_I)
   373 
   374 lemma finite_cartesian_product: "[| finite A; finite B |] ==>
   375     finite (A <*> B)"
   376   by (rule finite_SigmaI)
   377 
   378 lemma finite_Prod_UNIV:
   379     "finite (UNIV::'a set) ==> finite (UNIV::'b set) ==> finite (UNIV::('a * 'b) set)"
   380   apply (subgoal_tac "(UNIV:: ('a * 'b) set) = Sigma UNIV (%x. UNIV)")
   381    apply (erule ssubst)
   382    apply (erule finite_SigmaI, auto)
   383   done
   384 
   385 lemma finite_cartesian_productD1:
   386      "[| finite (A <*> B); B \<noteq> {} |] ==> finite A"
   387 apply (auto simp add: finite_conv_nat_seg_image) 
   388 apply (drule_tac x=n in spec) 
   389 apply (drule_tac x="fst o f" in spec) 
   390 apply (auto simp add: o_def) 
   391  prefer 2 apply (force dest!: equalityD2) 
   392 apply (drule equalityD1) 
   393 apply (rename_tac y x)
   394 apply (subgoal_tac "\<exists>k. k<n & f k = (x,y)") 
   395  prefer 2 apply force
   396 apply clarify
   397 apply (rule_tac x=k in image_eqI, auto)
   398 done
   399 
   400 lemma finite_cartesian_productD2:
   401      "[| finite (A <*> B); A \<noteq> {} |] ==> finite B"
   402 apply (auto simp add: finite_conv_nat_seg_image) 
   403 apply (drule_tac x=n in spec) 
   404 apply (drule_tac x="snd o f" in spec) 
   405 apply (auto simp add: o_def) 
   406  prefer 2 apply (force dest!: equalityD2) 
   407 apply (drule equalityD1)
   408 apply (rename_tac x y)
   409 apply (subgoal_tac "\<exists>k. k<n & f k = (x,y)") 
   410  prefer 2 apply force
   411 apply clarify
   412 apply (rule_tac x=k in image_eqI, auto)
   413 done
   414 
   415 
   416 text {* The powerset of a finite set *}
   417 
   418 lemma finite_Pow_iff [iff]: "finite (Pow A) = finite A"
   419 proof
   420   assume "finite (Pow A)"
   421   with _ have "finite ((%x. {x}) ` A)" by (rule finite_subset) blast
   422   thus "finite A" by (rule finite_imageD [unfolded inj_on_def]) simp
   423 next
   424   assume "finite A"
   425   thus "finite (Pow A)"
   426     by induct (simp_all add: finite_UnI finite_imageI Pow_insert)
   427 qed
   428 
   429 lemma finite_Collect_subsets[simp,intro]: "finite A \<Longrightarrow> finite{B. B \<subseteq> A}"
   430 by(simp add: Pow_def[symmetric])
   431 
   432 
   433 lemma finite_UnionD: "finite(\<Union>A) \<Longrightarrow> finite A"
   434 by(blast intro: finite_subset[OF subset_Pow_Union])
   435 
   436 
   437 subsection {* Class @{text finite}  *}
   438 
   439 setup {* Sign.add_path "finite" *} -- {*FIXME: name tweaking*}
   440 class finite =
   441   assumes finite_UNIV: "finite (UNIV \<Colon> 'a set)"
   442 setup {* Sign.parent_path *}
   443 hide const finite
   444 
   445 context finite
   446 begin
   447 
   448 lemma finite [simp]: "finite (A \<Colon> 'a set)"
   449   by (rule subset_UNIV finite_UNIV finite_subset)+
   450 
   451 end
   452 
   453 lemma UNIV_unit [noatp]:
   454   "UNIV = {()}" by auto
   455 
   456 instance unit :: finite
   457   by default (simp add: UNIV_unit)
   458 
   459 lemma UNIV_bool [noatp]:
   460   "UNIV = {False, True}" by auto
   461 
   462 instance bool :: finite
   463   by default (simp add: UNIV_bool)
   464 
   465 instance * :: (finite, finite) finite
   466   by default (simp only: UNIV_Times_UNIV [symmetric] finite_cartesian_product finite)
   467 
   468 lemma inj_graph: "inj (%f. {(x, y). y = f x})"
   469   by (rule inj_onI, auto simp add: expand_set_eq expand_fun_eq)
   470 
   471 instance "fun" :: (finite, finite) finite
   472 proof
   473   show "finite (UNIV :: ('a => 'b) set)"
   474   proof (rule finite_imageD)
   475     let ?graph = "%f::'a => 'b. {(x, y). y = f x}"
   476     have "range ?graph \<subseteq> Pow UNIV" by simp
   477     moreover have "finite (Pow (UNIV :: ('a * 'b) set))"
   478       by (simp only: finite_Pow_iff finite)
   479     ultimately show "finite (range ?graph)"
   480       by (rule finite_subset)
   481     show "inj ?graph" by (rule inj_graph)
   482   qed
   483 qed
   484 
   485 instance "+" :: (finite, finite) finite
   486   by default (simp only: UNIV_Plus_UNIV [symmetric] finite_Plus finite)
   487 
   488 
   489 subsection {* A fold functional for finite sets *}
   490 
   491 text {* The intended behaviour is
   492 @{text "fold f z {x\<^isub>1, ..., x\<^isub>n} = f x\<^isub>1 (\<dots> (f x\<^isub>n z)\<dots>)"}
   493 if @{text f} is ``left-commutative'':
   494 *}
   495 
   496 locale fun_left_comm =
   497   fixes f :: "'a \<Rightarrow> 'b \<Rightarrow> 'b"
   498   assumes fun_left_comm: "f x (f y z) = f y (f x z)"
   499 begin
   500 
   501 text{* On a functional level it looks much nicer: *}
   502 
   503 lemma fun_comp_comm:  "f x \<circ> f y = f y \<circ> f x"
   504 by (simp add: fun_left_comm expand_fun_eq)
   505 
   506 end
   507 
   508 inductive fold_graph :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a set \<Rightarrow> 'b \<Rightarrow> bool"
   509 for f :: "'a \<Rightarrow> 'b \<Rightarrow> 'b" and z :: 'b where
   510   emptyI [intro]: "fold_graph f z {} z" |
   511   insertI [intro]: "x \<notin> A \<Longrightarrow> fold_graph f z A y
   512       \<Longrightarrow> fold_graph f z (insert x A) (f x y)"
   513 
   514 inductive_cases empty_fold_graphE [elim!]: "fold_graph f z {} x"
   515 
   516 definition fold :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a set \<Rightarrow> 'b" where
   517 [code del]: "fold f z A = (THE y. fold_graph f z A y)"
   518 
   519 text{*A tempting alternative for the definiens is
   520 @{term "if finite A then THE y. fold_graph f z A y else e"}.
   521 It allows the removal of finiteness assumptions from the theorems
   522 @{text fold_comm}, @{text fold_reindex} and @{text fold_distrib}.
   523 The proofs become ugly. It is not worth the effort. (???) *}
   524 
   525 
   526 lemma Diff1_fold_graph:
   527   "fold_graph f z (A - {x}) y \<Longrightarrow> x \<in> A \<Longrightarrow> fold_graph f z A (f x y)"
   528 by (erule insert_Diff [THEN subst], rule fold_graph.intros, auto)
   529 
   530 lemma fold_graph_imp_finite: "fold_graph f z A x \<Longrightarrow> finite A"
   531 by (induct set: fold_graph) auto
   532 
   533 lemma finite_imp_fold_graph: "finite A \<Longrightarrow> \<exists>x. fold_graph f z A x"
   534 by (induct set: finite) auto
   535 
   536 
   537 subsubsection{*From @{const fold_graph} to @{term fold}*}
   538 
   539 lemma image_less_Suc: "h ` {i. i < Suc m} = insert (h m) (h ` {i. i < m})"
   540   by (auto simp add: less_Suc_eq) 
   541 
   542 lemma insert_image_inj_on_eq:
   543      "[|insert (h m) A = h ` {i. i < Suc m}; h m \<notin> A; 
   544         inj_on h {i. i < Suc m}|] 
   545       ==> A = h ` {i. i < m}"
   546 apply (auto simp add: image_less_Suc inj_on_def)
   547 apply (blast intro: less_trans) 
   548 done
   549 
   550 lemma insert_inj_onE:
   551   assumes aA: "insert a A = h`{i::nat. i<n}" and anot: "a \<notin> A" 
   552       and inj_on: "inj_on h {i::nat. i<n}"
   553   shows "\<exists>hm m. inj_on hm {i::nat. i<m} & A = hm ` {i. i<m} & m < n"
   554 proof (cases n)
   555   case 0 thus ?thesis using aA by auto
   556 next
   557   case (Suc m)
   558   have nSuc: "n = Suc m" by fact
   559   have mlessn: "m<n" by (simp add: nSuc)
   560   from aA obtain k where hkeq: "h k = a" and klessn: "k<n" by (blast elim!: equalityE)
   561   let ?hm = "Fun.swap k m h"
   562   have inj_hm: "inj_on ?hm {i. i < n}" using klessn mlessn 
   563     by (simp add: inj_on_swap_iff inj_on)
   564   show ?thesis
   565   proof (intro exI conjI)
   566     show "inj_on ?hm {i. i < m}" using inj_hm
   567       by (auto simp add: nSuc less_Suc_eq intro: subset_inj_on)
   568     show "m<n" by (rule mlessn)
   569     show "A = ?hm ` {i. i < m}" 
   570     proof (rule insert_image_inj_on_eq)
   571       show "inj_on (Fun.swap k m h) {i. i < Suc m}" using inj_hm nSuc by simp
   572       show "?hm m \<notin> A" by (simp add: swap_def hkeq anot) 
   573       show "insert (?hm m) A = ?hm ` {i. i < Suc m}"
   574 	using aA hkeq nSuc klessn
   575 	by (auto simp add: swap_def image_less_Suc fun_upd_image 
   576 			   less_Suc_eq inj_on_image_set_diff [OF inj_on])
   577     qed
   578   qed
   579 qed
   580 
   581 context fun_left_comm
   582 begin
   583 
   584 lemma fold_graph_determ_aux:
   585   "A = h`{i::nat. i<n} \<Longrightarrow> inj_on h {i. i<n}
   586    \<Longrightarrow> fold_graph f z A x \<Longrightarrow> fold_graph f z A x'
   587    \<Longrightarrow> x' = x"
   588 proof (induct n arbitrary: A x x' h rule: less_induct)
   589   case (less n)
   590   have IH: "\<And>m h A x x'. m < n \<Longrightarrow> A = h ` {i. i<m}
   591       \<Longrightarrow> inj_on h {i. i<m} \<Longrightarrow> fold_graph f z A x
   592       \<Longrightarrow> fold_graph f z A x' \<Longrightarrow> x' = x" by fact
   593   have Afoldx: "fold_graph f z A x" and Afoldx': "fold_graph f z A x'"
   594     and A: "A = h`{i. i<n}" and injh: "inj_on h {i. i<n}" by fact+
   595   show ?case
   596   proof (rule fold_graph.cases [OF Afoldx])
   597     assume "A = {}" and "x = z"
   598     with Afoldx' show "x' = x" by auto
   599   next
   600     fix B b u
   601     assume AbB: "A = insert b B" and x: "x = f b u"
   602       and notinB: "b \<notin> B" and Bu: "fold_graph f z B u"
   603     show "x'=x" 
   604     proof (rule fold_graph.cases [OF Afoldx'])
   605       assume "A = {}" and "x' = z"
   606       with AbB show "x' = x" by blast
   607     next
   608       fix C c v
   609       assume AcC: "A = insert c C" and x': "x' = f c v"
   610         and notinC: "c \<notin> C" and Cv: "fold_graph f z C v"
   611       from A AbB have Beq: "insert b B = h`{i. i<n}" by simp
   612       from insert_inj_onE [OF Beq notinB injh]
   613       obtain hB mB where inj_onB: "inj_on hB {i. i < mB}" 
   614         and Beq: "B = hB ` {i. i < mB}" and lessB: "mB < n" by auto 
   615       from A AcC have Ceq: "insert c C = h`{i. i<n}" by simp
   616       from insert_inj_onE [OF Ceq notinC injh]
   617       obtain hC mC where inj_onC: "inj_on hC {i. i < mC}"
   618         and Ceq: "C = hC ` {i. i < mC}" and lessC: "mC < n" by auto 
   619       show "x'=x"
   620       proof cases
   621         assume "b=c"
   622 	then moreover have "B = C" using AbB AcC notinB notinC by auto
   623 	ultimately show ?thesis  using Bu Cv x x' IH [OF lessC Ceq inj_onC]
   624           by auto
   625       next
   626 	assume diff: "b \<noteq> c"
   627 	let ?D = "B - {c}"
   628 	have B: "B = insert c ?D" and C: "C = insert b ?D"
   629 	  using AbB AcC notinB notinC diff by(blast elim!:equalityE)+
   630 	have "finite A" by(rule fold_graph_imp_finite [OF Afoldx])
   631 	with AbB have "finite ?D" by simp
   632 	then obtain d where Dfoldd: "fold_graph f z ?D d"
   633 	  using finite_imp_fold_graph by iprover
   634 	moreover have cinB: "c \<in> B" using B by auto
   635 	ultimately have "fold_graph f z B (f c d)" by(rule Diff1_fold_graph)
   636 	hence "f c d = u" by (rule IH [OF lessB Beq inj_onB Bu]) 
   637         moreover have "f b d = v"
   638 	proof (rule IH[OF lessC Ceq inj_onC Cv])
   639 	  show "fold_graph f z C (f b d)" using C notinB Dfoldd by fastsimp
   640 	qed
   641 	ultimately show ?thesis
   642           using fun_left_comm [of c b] x x' by (auto simp add: o_def)
   643       qed
   644     qed
   645   qed
   646 qed
   647 
   648 lemma fold_graph_determ:
   649   "fold_graph f z A x \<Longrightarrow> fold_graph f z A y \<Longrightarrow> y = x"
   650 apply (frule fold_graph_imp_finite [THEN finite_imp_nat_seg_image_inj_on]) 
   651 apply (blast intro: fold_graph_determ_aux [rule_format])
   652 done
   653 
   654 lemma fold_equality:
   655   "fold_graph f z A y \<Longrightarrow> fold f z A = y"
   656 by (unfold fold_def) (blast intro: fold_graph_determ)
   657 
   658 text{* The base case for @{text fold}: *}
   659 
   660 lemma (in -) fold_empty [simp]: "fold f z {} = z"
   661 by (unfold fold_def) blast
   662 
   663 text{* The various recursion equations for @{const fold}: *}
   664 
   665 lemma fold_insert_aux: "x \<notin> A
   666   \<Longrightarrow> fold_graph f z (insert x A) v \<longleftrightarrow>
   667       (\<exists>y. fold_graph f z A y \<and> v = f x y)"
   668 apply auto
   669 apply (rule_tac A1 = A and f1 = f in finite_imp_fold_graph [THEN exE])
   670  apply (fastsimp dest: fold_graph_imp_finite)
   671 apply (blast intro: fold_graph_determ)
   672 done
   673 
   674 lemma fold_insert [simp]:
   675   "finite A ==> x \<notin> A ==> fold f z (insert x A) = f x (fold f z A)"
   676 apply (simp add: fold_def fold_insert_aux)
   677 apply (rule the_equality)
   678  apply (auto intro: finite_imp_fold_graph
   679         cong add: conj_cong simp add: fold_def[symmetric] fold_equality)
   680 done
   681 
   682 lemma fold_fun_comm:
   683   "finite A \<Longrightarrow> f x (fold f z A) = fold f (f x z) A"
   684 proof (induct rule: finite_induct)
   685   case empty then show ?case by simp
   686 next
   687   case (insert y A) then show ?case
   688     by (simp add: fun_left_comm[of x])
   689 qed
   690 
   691 lemma fold_insert2:
   692   "finite A \<Longrightarrow> x \<notin> A \<Longrightarrow> fold f z (insert x A) = fold f (f x z) A"
   693 by (simp add: fold_insert fold_fun_comm)
   694 
   695 lemma fold_rec:
   696 assumes "finite A" and "x \<in> A"
   697 shows "fold f z A = f x (fold f z (A - {x}))"
   698 proof -
   699   have A: "A = insert x (A - {x})" using `x \<in> A` by blast
   700   then have "fold f z A = fold f z (insert x (A - {x}))" by simp
   701   also have "\<dots> = f x (fold f z (A - {x}))"
   702     by (rule fold_insert) (simp add: `finite A`)+
   703   finally show ?thesis .
   704 qed
   705 
   706 lemma fold_insert_remove:
   707   assumes "finite A"
   708   shows "fold f z (insert x A) = f x (fold f z (A - {x}))"
   709 proof -
   710   from `finite A` have "finite (insert x A)" by auto
   711   moreover have "x \<in> insert x A" by auto
   712   ultimately have "fold f z (insert x A) = f x (fold f z (insert x A - {x}))"
   713     by (rule fold_rec)
   714   then show ?thesis by simp
   715 qed
   716 
   717 end
   718 
   719 text{* A simplified version for idempotent functions: *}
   720 
   721 locale fun_left_comm_idem = fun_left_comm +
   722   assumes fun_left_idem: "f x (f x z) = f x z"
   723 begin
   724 
   725 text{* The nice version: *}
   726 lemma fun_comp_idem : "f x o f x = f x"
   727 by (simp add: fun_left_idem expand_fun_eq)
   728 
   729 lemma fold_insert_idem:
   730   assumes fin: "finite A"
   731   shows "fold f z (insert x A) = f x (fold f z A)"
   732 proof cases
   733   assume "x \<in> A"
   734   then obtain B where "A = insert x B" and "x \<notin> B" by (rule set_insert)
   735   then show ?thesis using assms by (simp add:fun_left_idem)
   736 next
   737   assume "x \<notin> A" then show ?thesis using assms by simp
   738 qed
   739 
   740 declare fold_insert[simp del] fold_insert_idem[simp]
   741 
   742 lemma fold_insert_idem2:
   743   "finite A \<Longrightarrow> fold f z (insert x A) = fold f (f x z) A"
   744 by(simp add:fold_fun_comm)
   745 
   746 end
   747 
   748 subsubsection{* The derived combinator @{text fold_image} *}
   749 
   750 definition fold_image :: "('b \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a set \<Rightarrow> 'b"
   751 where "fold_image f g = fold (%x y. f (g x) y)"
   752 
   753 lemma fold_image_empty[simp]: "fold_image f g z {} = z"
   754 by(simp add:fold_image_def)
   755 
   756 context ab_semigroup_mult
   757 begin
   758 
   759 lemma fold_image_insert[simp]:
   760 assumes "finite A" and "a \<notin> A"
   761 shows "fold_image times g z (insert a A) = g a * (fold_image times g z A)"
   762 proof -
   763   interpret I: fun_left_comm "%x y. (g x) * y"
   764     by unfold_locales (simp add: mult_ac)
   765   show ?thesis using assms by(simp add:fold_image_def I.fold_insert)
   766 qed
   767 
   768 (*
   769 lemma fold_commute:
   770   "finite A ==> (!!z. x * (fold times g z A) = fold times g (x * z) A)"
   771   apply (induct set: finite)
   772    apply simp
   773   apply (simp add: mult_left_commute [of x])
   774   done
   775 
   776 lemma fold_nest_Un_Int:
   777   "finite A ==> finite B
   778     ==> fold times g (fold times g z B) A = fold times g (fold times g z (A Int B)) (A Un B)"
   779   apply (induct set: finite)
   780    apply simp
   781   apply (simp add: fold_commute Int_insert_left insert_absorb)
   782   done
   783 
   784 lemma fold_nest_Un_disjoint:
   785   "finite A ==> finite B ==> A Int B = {}
   786     ==> fold times g z (A Un B) = fold times g (fold times g z B) A"
   787   by (simp add: fold_nest_Un_Int)
   788 *)
   789 
   790 lemma fold_image_reindex:
   791 assumes fin: "finite A"
   792 shows "inj_on h A \<Longrightarrow> fold_image times g z (h`A) = fold_image times (g\<circ>h) z A"
   793 using fin apply induct
   794  apply simp
   795 apply simp
   796 done
   797 
   798 (*
   799 text{*
   800   Fusion theorem, as described in Graham Hutton's paper,
   801   A Tutorial on the Universality and Expressiveness of Fold,
   802   JFP 9:4 (355-372), 1999.
   803 *}
   804 
   805 lemma fold_fusion:
   806   assumes "ab_semigroup_mult g"
   807   assumes fin: "finite A"
   808     and hyp: "\<And>x y. h (g x y) = times x (h y)"
   809   shows "h (fold g j w A) = fold times j (h w) A"
   810 proof -
   811   class_interpret ab_semigroup_mult [g] by fact
   812   show ?thesis using fin hyp by (induct set: finite) simp_all
   813 qed
   814 *)
   815 
   816 lemma fold_image_cong:
   817   "finite A \<Longrightarrow>
   818   (!!x. x:A ==> g x = h x) ==> fold_image times g z A = fold_image times h z A"
   819 apply (subgoal_tac "ALL C. C <= A --> (ALL x:C. g x = h x) --> fold_image times g z C = fold_image times h z C")
   820  apply simp
   821 apply (erule finite_induct, simp)
   822 apply (simp add: subset_insert_iff, clarify)
   823 apply (subgoal_tac "finite C")
   824  prefer 2 apply (blast dest: finite_subset [COMP swap_prems_rl])
   825 apply (subgoal_tac "C = insert x (C - {x})")
   826  prefer 2 apply blast
   827 apply (erule ssubst)
   828 apply (drule spec)
   829 apply (erule (1) notE impE)
   830 apply (simp add: Ball_def del: insert_Diff_single)
   831 done
   832 
   833 end
   834 
   835 context comm_monoid_mult
   836 begin
   837 
   838 lemma fold_image_Un_Int:
   839   "finite A ==> finite B ==>
   840     fold_image times g 1 A * fold_image times g 1 B =
   841     fold_image times g 1 (A Un B) * fold_image times g 1 (A Int B)"
   842 by (induct set: finite) 
   843    (auto simp add: mult_ac insert_absorb Int_insert_left)
   844 
   845 corollary fold_Un_disjoint:
   846   "finite A ==> finite B ==> A Int B = {} ==>
   847    fold_image times g 1 (A Un B) =
   848    fold_image times g 1 A * fold_image times g 1 B"
   849 by (simp add: fold_image_Un_Int)
   850 
   851 lemma fold_image_UN_disjoint:
   852   "\<lbrakk> finite I; ALL i:I. finite (A i);
   853      ALL i:I. ALL j:I. i \<noteq> j --> A i Int A j = {} \<rbrakk>
   854    \<Longrightarrow> fold_image times g 1 (UNION I A) =
   855        fold_image times (%i. fold_image times g 1 (A i)) 1 I"
   856 apply (induct set: finite, simp, atomize)
   857 apply (subgoal_tac "ALL i:F. x \<noteq> i")
   858  prefer 2 apply blast
   859 apply (subgoal_tac "A x Int UNION F A = {}")
   860  prefer 2 apply blast
   861 apply (simp add: fold_Un_disjoint)
   862 done
   863 
   864 lemma fold_image_Sigma: "finite A ==> ALL x:A. finite (B x) ==>
   865   fold_image times (%x. fold_image times (g x) 1 (B x)) 1 A =
   866   fold_image times (split g) 1 (SIGMA x:A. B x)"
   867 apply (subst Sigma_def)
   868 apply (subst fold_image_UN_disjoint, assumption, simp)
   869  apply blast
   870 apply (erule fold_image_cong)
   871 apply (subst fold_image_UN_disjoint, simp, simp)
   872  apply blast
   873 apply simp
   874 done
   875 
   876 lemma fold_image_distrib: "finite A \<Longrightarrow>
   877    fold_image times (%x. g x * h x) 1 A =
   878    fold_image times g 1 A *  fold_image times h 1 A"
   879 by (erule finite_induct) (simp_all add: mult_ac)
   880 
   881 lemma fold_image_related: 
   882   assumes Re: "R e e" 
   883   and Rop: "\<forall>x1 y1 x2 y2. R x1 x2 \<and> R y1 y2 \<longrightarrow> R (x1 * y1) (x2 * y2)" 
   884   and fS: "finite S" and Rfg: "\<forall>x\<in>S. R (h x) (g x)"
   885   shows "R (fold_image (op *) h e S) (fold_image (op *) g e S)"
   886   using fS by (rule finite_subset_induct) (insert assms, auto)
   887 
   888 lemma  fold_image_eq_general:
   889   assumes fS: "finite S"
   890   and h: "\<forall>y\<in>S'. \<exists>!x. x\<in> S \<and> h(x) = y" 
   891   and f12:  "\<forall>x\<in>S. h x \<in> S' \<and> f2(h x) = f1 x"
   892   shows "fold_image (op *) f1 e S = fold_image (op *) f2 e S'"
   893 proof-
   894   from h f12 have hS: "h ` S = S'" by auto
   895   {fix x y assume H: "x \<in> S" "y \<in> S" "h x = h y"
   896     from f12 h H  have "x = y" by auto }
   897   hence hinj: "inj_on h S" unfolding inj_on_def Ex1_def by blast
   898   from f12 have th: "\<And>x. x \<in> S \<Longrightarrow> (f2 \<circ> h) x = f1 x" by auto 
   899   from hS have "fold_image (op *) f2 e S' = fold_image (op *) f2 e (h ` S)" by simp
   900   also have "\<dots> = fold_image (op *) (f2 o h) e S" 
   901     using fold_image_reindex[OF fS hinj, of f2 e] .
   902   also have "\<dots> = fold_image (op *) f1 e S " using th fold_image_cong[OF fS, of "f2 o h" f1 e]
   903     by blast
   904   finally show ?thesis ..
   905 qed
   906 
   907 lemma fold_image_eq_general_inverses:
   908   assumes fS: "finite S" 
   909   and kh: "\<And>y. y \<in> T \<Longrightarrow> k y \<in> S \<and> h (k y) = y"
   910   and hk: "\<And>x. x \<in> S \<Longrightarrow> h x \<in> T \<and> k (h x) = x  \<and> g (h x) = f x"
   911   shows "fold_image (op *) f e S = fold_image (op *) g e T"
   912   (* metis solves it, but not yet available here *)
   913   apply (rule fold_image_eq_general[OF fS, of T h g f e])
   914   apply (rule ballI)
   915   apply (frule kh)
   916   apply (rule ex1I[])
   917   apply blast
   918   apply clarsimp
   919   apply (drule hk) apply simp
   920   apply (rule sym)
   921   apply (erule conjunct1[OF conjunct2[OF hk]])
   922   apply (rule ballI)
   923   apply (drule  hk)
   924   apply blast
   925   done
   926 
   927 end
   928 
   929 subsection {* Generalized summation over a set *}
   930 
   931 interpretation comm_monoid_add: comm_monoid_mult "0::'a::comm_monoid_add" "op +"
   932   proof qed (auto intro: add_assoc add_commute)
   933 
   934 definition setsum :: "('a => 'b) => 'a set => 'b::comm_monoid_add"
   935 where "setsum f A == if finite A then fold_image (op +) f 0 A else 0"
   936 
   937 abbreviation
   938   Setsum  ("\<Sum>_" [1000] 999) where
   939   "\<Sum>A == setsum (%x. x) A"
   940 
   941 text{* Now: lot's of fancy syntax. First, @{term "setsum (%x. e) A"} is
   942 written @{text"\<Sum>x\<in>A. e"}. *}
   943 
   944 syntax
   945   "_setsum" :: "pttrn => 'a set => 'b => 'b::comm_monoid_add"    ("(3SUM _:_. _)" [0, 51, 10] 10)
   946 syntax (xsymbols)
   947   "_setsum" :: "pttrn => 'a set => 'b => 'b::comm_monoid_add"    ("(3\<Sum>_\<in>_. _)" [0, 51, 10] 10)
   948 syntax (HTML output)
   949   "_setsum" :: "pttrn => 'a set => 'b => 'b::comm_monoid_add"    ("(3\<Sum>_\<in>_. _)" [0, 51, 10] 10)
   950 
   951 translations -- {* Beware of argument permutation! *}
   952   "SUM i:A. b" == "CONST setsum (%i. b) A"
   953   "\<Sum>i\<in>A. b" == "CONST setsum (%i. b) A"
   954 
   955 text{* Instead of @{term"\<Sum>x\<in>{x. P}. e"} we introduce the shorter
   956  @{text"\<Sum>x|P. e"}. *}
   957 
   958 syntax
   959   "_qsetsum" :: "pttrn \<Rightarrow> bool \<Rightarrow> 'a \<Rightarrow> 'a" ("(3SUM _ |/ _./ _)" [0,0,10] 10)
   960 syntax (xsymbols)
   961   "_qsetsum" :: "pttrn \<Rightarrow> bool \<Rightarrow> 'a \<Rightarrow> 'a" ("(3\<Sum>_ | (_)./ _)" [0,0,10] 10)
   962 syntax (HTML output)
   963   "_qsetsum" :: "pttrn \<Rightarrow> bool \<Rightarrow> 'a \<Rightarrow> 'a" ("(3\<Sum>_ | (_)./ _)" [0,0,10] 10)
   964 
   965 translations
   966   "SUM x|P. t" => "CONST setsum (%x. t) {x. P}"
   967   "\<Sum>x|P. t" => "CONST setsum (%x. t) {x. P}"
   968 
   969 print_translation {*
   970 let
   971   fun setsum_tr' [Abs(x,Tx,t), Const ("Collect",_) $ Abs(y,Ty,P)] = 
   972     if x<>y then raise Match
   973     else let val x' = Syntax.mark_bound x
   974              val t' = subst_bound(x',t)
   975              val P' = subst_bound(x',P)
   976          in Syntax.const "_qsetsum" $ Syntax.mark_bound x $ P' $ t' end
   977 in [("setsum", setsum_tr')] end
   978 *}
   979 
   980 
   981 lemma setsum_empty [simp]: "setsum f {} = 0"
   982 by (simp add: setsum_def)
   983 
   984 lemma setsum_insert [simp]:
   985   "finite F ==> a \<notin> F ==> setsum f (insert a F) = f a + setsum f F"
   986 by (simp add: setsum_def)
   987 
   988 lemma setsum_infinite [simp]: "~ finite A ==> setsum f A = 0"
   989 by (simp add: setsum_def)
   990 
   991 lemma setsum_reindex:
   992      "inj_on f B ==> setsum h (f ` B) = setsum (h \<circ> f) B"
   993 by(auto simp add: setsum_def comm_monoid_add.fold_image_reindex dest!:finite_imageD)
   994 
   995 lemma setsum_reindex_id:
   996      "inj_on f B ==> setsum f B = setsum id (f ` B)"
   997 by (auto simp add: setsum_reindex)
   998 
   999 lemma setsum_reindex_nonzero: 
  1000   assumes fS: "finite S"
  1001   and nz: "\<And> x y. x \<in> S \<Longrightarrow> y \<in> S \<Longrightarrow> x \<noteq> y \<Longrightarrow> f x = f y \<Longrightarrow> h (f x) = 0"
  1002   shows "setsum h (f ` S) = setsum (h o f) S"
  1003 using nz
  1004 proof(induct rule: finite_induct[OF fS])
  1005   case 1 thus ?case by simp
  1006 next
  1007   case (2 x F) 
  1008   {assume fxF: "f x \<in> f ` F" hence "\<exists>y \<in> F . f y = f x" by auto
  1009     then obtain y where y: "y \<in> F" "f x = f y" by auto 
  1010     from "2.hyps" y have xy: "x \<noteq> y" by auto
  1011     
  1012     from "2.prems"[of x y] "2.hyps" xy y have h0: "h (f x) = 0" by simp
  1013     have "setsum h (f ` insert x F) = setsum h (f ` F)" using fxF by auto
  1014     also have "\<dots> = setsum (h o f) (insert x F)" 
  1015       unfolding setsum_insert[OF `finite F` `x\<notin>F`]
  1016       using h0 
  1017       apply simp
  1018       apply (rule "2.hyps"(3))
  1019       apply (rule_tac y="y" in  "2.prems")
  1020       apply simp_all
  1021       done
  1022     finally have ?case .}
  1023   moreover
  1024   {assume fxF: "f x \<notin> f ` F"
  1025     have "setsum h (f ` insert x F) = h (f x) + setsum h (f ` F)" 
  1026       using fxF "2.hyps" by simp 
  1027     also have "\<dots> = setsum (h o f) (insert x F)"
  1028       unfolding setsum_insert[OF `finite F` `x\<notin>F`]
  1029       apply simp
  1030       apply (rule cong[OF refl[of "op + (h (f x))"]])
  1031       apply (rule "2.hyps"(3))
  1032       apply (rule_tac y="y" in  "2.prems")
  1033       apply simp_all
  1034       done
  1035     finally have ?case .}
  1036   ultimately show ?case by blast
  1037 qed
  1038 
  1039 lemma setsum_cong:
  1040   "A = B ==> (!!x. x:B ==> f x = g x) ==> setsum f A = setsum g B"
  1041 by(fastsimp simp: setsum_def intro: comm_monoid_add.fold_image_cong)
  1042 
  1043 lemma strong_setsum_cong[cong]:
  1044   "A = B ==> (!!x. x:B =simp=> f x = g x)
  1045    ==> setsum (%x. f x) A = setsum (%x. g x) B"
  1046 by(fastsimp simp: simp_implies_def setsum_def intro: comm_monoid_add.fold_image_cong)
  1047 
  1048 lemma setsum_cong2: "\<lbrakk>\<And>x. x \<in> A \<Longrightarrow> f x = g x\<rbrakk> \<Longrightarrow> setsum f A = setsum g A";
  1049 by (rule setsum_cong[OF refl], auto);
  1050 
  1051 lemma setsum_reindex_cong:
  1052    "[|inj_on f A; B = f ` A; !!a. a:A \<Longrightarrow> g a = h (f a)|] 
  1053     ==> setsum h B = setsum g A"
  1054 by (simp add: setsum_reindex cong: setsum_cong)
  1055 
  1056 
  1057 lemma setsum_0[simp]: "setsum (%i. 0) A = 0"
  1058 apply (clarsimp simp: setsum_def)
  1059 apply (erule finite_induct, auto)
  1060 done
  1061 
  1062 lemma setsum_0': "ALL a:A. f a = 0 ==> setsum f A = 0"
  1063 by(simp add:setsum_cong)
  1064 
  1065 lemma setsum_Un_Int: "finite A ==> finite B ==>
  1066   setsum g (A Un B) + setsum g (A Int B) = setsum g A + setsum g B"
  1067   -- {* The reversed orientation looks more natural, but LOOPS as a simprule! *}
  1068 by(simp add: setsum_def comm_monoid_add.fold_image_Un_Int [symmetric])
  1069 
  1070 lemma setsum_Un_disjoint: "finite A ==> finite B
  1071   ==> A Int B = {} ==> setsum g (A Un B) = setsum g A + setsum g B"
  1072 by (subst setsum_Un_Int [symmetric], auto)
  1073 
  1074 lemma setsum_mono_zero_left: 
  1075   assumes fT: "finite T" and ST: "S \<subseteq> T"
  1076   and z: "\<forall>i \<in> T - S. f i = 0"
  1077   shows "setsum f S = setsum f T"
  1078 proof-
  1079   have eq: "T = S \<union> (T - S)" using ST by blast
  1080   have d: "S \<inter> (T - S) = {}" using ST by blast
  1081   from fT ST have f: "finite S" "finite (T - S)" by (auto intro: finite_subset)
  1082   show ?thesis 
  1083   by (simp add: setsum_Un_disjoint[OF f d, unfolded eq[symmetric]] setsum_0'[OF z])
  1084 qed
  1085 
  1086 lemma setsum_mono_zero_right: 
  1087   "finite T \<Longrightarrow> S \<subseteq> T \<Longrightarrow> \<forall>i \<in> T - S. f i = 0 \<Longrightarrow> setsum f T = setsum f S"
  1088 by(blast intro!: setsum_mono_zero_left[symmetric])
  1089 
  1090 lemma setsum_mono_zero_cong_left: 
  1091   assumes fT: "finite T" and ST: "S \<subseteq> T"
  1092   and z: "\<forall>i \<in> T - S. g i = 0"
  1093   and fg: "\<And>x. x \<in> S \<Longrightarrow> f x = g x"
  1094   shows "setsum f S = setsum g T"
  1095 proof-
  1096   have eq: "T = S \<union> (T - S)" using ST by blast
  1097   have d: "S \<inter> (T - S) = {}" using ST by blast
  1098   from fT ST have f: "finite S" "finite (T - S)" by (auto intro: finite_subset)
  1099   show ?thesis 
  1100     using fg by (simp add: setsum_Un_disjoint[OF f d, unfolded eq[symmetric]] setsum_0'[OF z])
  1101 qed
  1102 
  1103 lemma setsum_mono_zero_cong_right: 
  1104   assumes fT: "finite T" and ST: "S \<subseteq> T"
  1105   and z: "\<forall>i \<in> T - S. f i = 0"
  1106   and fg: "\<And>x. x \<in> S \<Longrightarrow> f x = g x"
  1107   shows "setsum f T = setsum g S"
  1108 using setsum_mono_zero_cong_left[OF fT ST z] fg[symmetric] by auto 
  1109 
  1110 lemma setsum_delta: 
  1111   assumes fS: "finite S"
  1112   shows "setsum (\<lambda>k. if k=a then b k else 0) S = (if a \<in> S then b a else 0)"
  1113 proof-
  1114   let ?f = "(\<lambda>k. if k=a then b k else 0)"
  1115   {assume a: "a \<notin> S"
  1116     hence "\<forall> k\<in> S. ?f k = 0" by simp
  1117     hence ?thesis  using a by simp}
  1118   moreover 
  1119   {assume a: "a \<in> S"
  1120     let ?A = "S - {a}"
  1121     let ?B = "{a}"
  1122     have eq: "S = ?A \<union> ?B" using a by blast 
  1123     have dj: "?A \<inter> ?B = {}" by simp
  1124     from fS have fAB: "finite ?A" "finite ?B" by auto  
  1125     have "setsum ?f S = setsum ?f ?A + setsum ?f ?B"
  1126       using setsum_Un_disjoint[OF fAB dj, of ?f, unfolded eq[symmetric]]
  1127       by simp
  1128     then have ?thesis  using a by simp}
  1129   ultimately show ?thesis by blast
  1130 qed
  1131 lemma setsum_delta': 
  1132   assumes fS: "finite S" shows 
  1133   "setsum (\<lambda>k. if a = k then b k else 0) S = 
  1134      (if a\<in> S then b a else 0)"
  1135   using setsum_delta[OF fS, of a b, symmetric] 
  1136   by (auto intro: setsum_cong)
  1137 
  1138 lemma setsum_restrict_set:
  1139   assumes fA: "finite A"
  1140   shows "setsum f (A \<inter> B) = setsum (\<lambda>x. if x \<in> B then f x else 0) A"
  1141 proof-
  1142   from fA have fab: "finite (A \<inter> B)" by auto
  1143   have aba: "A \<inter> B \<subseteq> A" by blast
  1144   let ?g = "\<lambda>x. if x \<in> A\<inter>B then f x else 0"
  1145   from setsum_mono_zero_left[OF fA aba, of ?g]
  1146   show ?thesis by simp
  1147 qed
  1148 
  1149 lemma setsum_cases:
  1150   assumes fA: "finite A"
  1151   shows "setsum (\<lambda>x. if x \<in> B then f x else g x) A =
  1152          setsum f (A \<inter> B) + setsum g (A \<inter> - B)"
  1153 proof-
  1154   have a: "A = A \<inter> B \<union> A \<inter> -B" "(A \<inter> B) \<inter> (A \<inter> -B) = {}" 
  1155     by blast+
  1156   from fA 
  1157   have f: "finite (A \<inter> B)" "finite (A \<inter> -B)" by auto
  1158   let ?g = "\<lambda>x. if x \<in> B then f x else g x"
  1159   from setsum_Un_disjoint[OF f a(2), of ?g] a(1)
  1160   show ?thesis by simp
  1161 qed
  1162 
  1163 
  1164 (*But we can't get rid of finite I. If infinite, although the rhs is 0, 
  1165   the lhs need not be, since UNION I A could still be finite.*)
  1166 lemma setsum_UN_disjoint:
  1167     "finite I ==> (ALL i:I. finite (A i)) ==>
  1168         (ALL i:I. ALL j:I. i \<noteq> j --> A i Int A j = {}) ==>
  1169       setsum f (UNION I A) = (\<Sum>i\<in>I. setsum f (A i))"
  1170 by(simp add: setsum_def comm_monoid_add.fold_image_UN_disjoint cong: setsum_cong)
  1171 
  1172 text{*No need to assume that @{term C} is finite.  If infinite, the rhs is
  1173 directly 0, and @{term "Union C"} is also infinite, hence the lhs is also 0.*}
  1174 lemma setsum_Union_disjoint:
  1175   "[| (ALL A:C. finite A);
  1176       (ALL A:C. ALL B:C. A \<noteq> B --> A Int B = {}) |]
  1177    ==> setsum f (Union C) = setsum (setsum f) C"
  1178 apply (cases "finite C") 
  1179  prefer 2 apply (force dest: finite_UnionD simp add: setsum_def)
  1180   apply (frule setsum_UN_disjoint [of C id f])
  1181  apply (unfold Union_def id_def, assumption+)
  1182 done
  1183 
  1184 (*But we can't get rid of finite A. If infinite, although the lhs is 0, 
  1185   the rhs need not be, since SIGMA A B could still be finite.*)
  1186 lemma setsum_Sigma: "finite A ==> ALL x:A. finite (B x) ==>
  1187     (\<Sum>x\<in>A. (\<Sum>y\<in>B x. f x y)) = (\<Sum>(x,y)\<in>(SIGMA x:A. B x). f x y)"
  1188 by(simp add:setsum_def comm_monoid_add.fold_image_Sigma split_def cong:setsum_cong)
  1189 
  1190 text{*Here we can eliminate the finiteness assumptions, by cases.*}
  1191 lemma setsum_cartesian_product: 
  1192    "(\<Sum>x\<in>A. (\<Sum>y\<in>B. f x y)) = (\<Sum>(x,y) \<in> A <*> B. f x y)"
  1193 apply (cases "finite A") 
  1194  apply (cases "finite B") 
  1195   apply (simp add: setsum_Sigma)
  1196  apply (cases "A={}", simp)
  1197  apply (simp) 
  1198 apply (auto simp add: setsum_def
  1199             dest: finite_cartesian_productD1 finite_cartesian_productD2) 
  1200 done
  1201 
  1202 lemma setsum_addf: "setsum (%x. f x + g x) A = (setsum f A + setsum g A)"
  1203 by(simp add:setsum_def comm_monoid_add.fold_image_distrib)
  1204 
  1205 
  1206 subsubsection {* Properties in more restricted classes of structures *}
  1207 
  1208 lemma setsum_SucD: "setsum f A = Suc n ==> EX a:A. 0 < f a"
  1209 apply (case_tac "finite A")
  1210  prefer 2 apply (simp add: setsum_def)
  1211 apply (erule rev_mp)
  1212 apply (erule finite_induct, auto)
  1213 done
  1214 
  1215 lemma setsum_eq_0_iff [simp]:
  1216     "finite F ==> (setsum f F = 0) = (ALL a:F. f a = (0::nat))"
  1217 by (induct set: finite) auto
  1218 
  1219 lemma setsum_Un_nat: "finite A ==> finite B ==>
  1220   (setsum f (A Un B) :: nat) = setsum f A + setsum f B - setsum f (A Int B)"
  1221   -- {* For the natural numbers, we have subtraction. *}
  1222 by (subst setsum_Un_Int [symmetric], auto simp add: algebra_simps)
  1223 
  1224 lemma setsum_Un: "finite A ==> finite B ==>
  1225   (setsum f (A Un B) :: 'a :: ab_group_add) =
  1226    setsum f A + setsum f B - setsum f (A Int B)"
  1227 by (subst setsum_Un_Int [symmetric], auto simp add: algebra_simps)
  1228 
  1229 lemma (in comm_monoid_mult) fold_image_1: "finite S \<Longrightarrow> (\<forall>x\<in>S. f x = 1) \<Longrightarrow> fold_image op * f 1 S = 1"
  1230   apply (induct set: finite)
  1231   apply simp by (auto simp add: fold_image_insert)
  1232 
  1233 lemma (in comm_monoid_mult) fold_image_Un_one:
  1234   assumes fS: "finite S" and fT: "finite T"
  1235   and I0: "\<forall>x \<in> S\<inter>T. f x = 1"
  1236   shows "fold_image (op *) f 1 (S \<union> T) = fold_image (op *) f 1 S * fold_image (op *) f 1 T"
  1237 proof-
  1238   have "fold_image op * f 1 (S \<inter> T) = 1" 
  1239     apply (rule fold_image_1)
  1240     using fS fT I0 by auto 
  1241   with fold_image_Un_Int[OF fS fT] show ?thesis by simp
  1242 qed
  1243 
  1244 lemma setsum_eq_general_reverses:
  1245   assumes fS: "finite S" and fT: "finite T"
  1246   and kh: "\<And>y. y \<in> T \<Longrightarrow> k y \<in> S \<and> h (k y) = y"
  1247   and hk: "\<And>x. x \<in> S \<Longrightarrow> h x \<in> T \<and> k (h x) = x \<and> g (h x) = f x"
  1248   shows "setsum f S = setsum g T"
  1249   apply (simp add: setsum_def fS fT)
  1250   apply (rule comm_monoid_add.fold_image_eq_general_inverses[OF fS])
  1251   apply (erule kh)
  1252   apply (erule hk)
  1253   done
  1254 
  1255 
  1256 
  1257 lemma setsum_Un_zero:  
  1258   assumes fS: "finite S" and fT: "finite T"
  1259   and I0: "\<forall>x \<in> S\<inter>T. f x = 0"
  1260   shows "setsum f (S \<union> T) = setsum f S  + setsum f T"
  1261   using fS fT
  1262   apply (simp add: setsum_def)
  1263   apply (rule comm_monoid_add.fold_image_Un_one)
  1264   using I0 by auto
  1265 
  1266 
  1267 lemma setsum_UNION_zero: 
  1268   assumes fS: "finite S" and fSS: "\<forall>T \<in> S. finite T"
  1269   and f0: "\<And>T1 T2 x. T1\<in>S \<Longrightarrow> T2\<in>S \<Longrightarrow> T1 \<noteq> T2 \<Longrightarrow> x \<in> T1 \<Longrightarrow> x \<in> T2 \<Longrightarrow> f x = 0"
  1270   shows "setsum f (\<Union>S) = setsum (\<lambda>T. setsum f T) S"
  1271   using fSS f0
  1272 proof(induct rule: finite_induct[OF fS])
  1273   case 1 thus ?case by simp
  1274 next
  1275   case (2 T F)
  1276   then have fTF: "finite T" "\<forall>T\<in>F. finite T" "finite F" and TF: "T \<notin> F" 
  1277     and H: "setsum f (\<Union> F) = setsum (setsum f) F" by (auto simp add: finite_insert)
  1278   from fTF have fUF: "finite (\<Union>F)" by (auto intro: finite_Union)
  1279   from "2.prems" TF fTF
  1280   show ?case 
  1281     by (auto simp add: H[symmetric] intro: setsum_Un_zero[OF fTF(1) fUF, of f])
  1282 qed
  1283 
  1284 
  1285 lemma setsum_diff1_nat: "(setsum f (A - {a}) :: nat) =
  1286   (if a:A then setsum f A - f a else setsum f A)"
  1287 apply (case_tac "finite A")
  1288  prefer 2 apply (simp add: setsum_def)
  1289 apply (erule finite_induct)
  1290  apply (auto simp add: insert_Diff_if)
  1291 apply (drule_tac a = a in mk_disjoint_insert, auto)
  1292 done
  1293 
  1294 lemma setsum_diff1: "finite A \<Longrightarrow>
  1295   (setsum f (A - {a}) :: ('a::ab_group_add)) =
  1296   (if a:A then setsum f A - f a else setsum f A)"
  1297 by (erule finite_induct) (auto simp add: insert_Diff_if)
  1298 
  1299 lemma setsum_diff1'[rule_format]:
  1300   "finite A \<Longrightarrow> a \<in> A \<longrightarrow> (\<Sum> x \<in> A. f x) = f a + (\<Sum> x \<in> (A - {a}). f x)"
  1301 apply (erule finite_induct[where F=A and P="% A. (a \<in> A \<longrightarrow> (\<Sum> x \<in> A. f x) = f a + (\<Sum> x \<in> (A - {a}). f x))"])
  1302 apply (auto simp add: insert_Diff_if add_ac)
  1303 done
  1304 
  1305 (* By Jeremy Siek: *)
  1306 
  1307 lemma setsum_diff_nat: 
  1308 assumes "finite B" and "B \<subseteq> A"
  1309 shows "(setsum f (A - B) :: nat) = (setsum f A) - (setsum f B)"
  1310 using assms
  1311 proof induct
  1312   show "setsum f (A - {}) = (setsum f A) - (setsum f {})" by simp
  1313 next
  1314   fix F x assume finF: "finite F" and xnotinF: "x \<notin> F"
  1315     and xFinA: "insert x F \<subseteq> A"
  1316     and IH: "F \<subseteq> A \<Longrightarrow> setsum f (A - F) = setsum f A - setsum f F"
  1317   from xnotinF xFinA have xinAF: "x \<in> (A - F)" by simp
  1318   from xinAF have A: "setsum f ((A - F) - {x}) = setsum f (A - F) - f x"
  1319     by (simp add: setsum_diff1_nat)
  1320   from xFinA have "F \<subseteq> A" by simp
  1321   with IH have "setsum f (A - F) = setsum f A - setsum f F" by simp
  1322   with A have B: "setsum f ((A - F) - {x}) = setsum f A - setsum f F - f x"
  1323     by simp
  1324   from xnotinF have "A - insert x F = (A - F) - {x}" by auto
  1325   with B have C: "setsum f (A - insert x F) = setsum f A - setsum f F - f x"
  1326     by simp
  1327   from finF xnotinF have "setsum f (insert x F) = setsum f F + f x" by simp
  1328   with C have "setsum f (A - insert x F) = setsum f A - setsum f (insert x F)"
  1329     by simp
  1330   thus "setsum f (A - insert x F) = setsum f A - setsum f (insert x F)" by simp
  1331 qed
  1332 
  1333 lemma setsum_diff:
  1334   assumes le: "finite A" "B \<subseteq> A"
  1335   shows "setsum f (A - B) = setsum f A - ((setsum f B)::('a::ab_group_add))"
  1336 proof -
  1337   from le have finiteB: "finite B" using finite_subset by auto
  1338   show ?thesis using finiteB le
  1339   proof induct
  1340     case empty
  1341     thus ?case by auto
  1342   next
  1343     case (insert x F)
  1344     thus ?case using le finiteB 
  1345       by (simp add: Diff_insert[where a=x and B=F] setsum_diff1 insert_absorb)
  1346   qed
  1347 qed
  1348 
  1349 lemma setsum_mono:
  1350   assumes le: "\<And>i. i\<in>K \<Longrightarrow> f (i::'a) \<le> ((g i)::('b::{comm_monoid_add, pordered_ab_semigroup_add}))"
  1351   shows "(\<Sum>i\<in>K. f i) \<le> (\<Sum>i\<in>K. g i)"
  1352 proof (cases "finite K")
  1353   case True
  1354   thus ?thesis using le
  1355   proof induct
  1356     case empty
  1357     thus ?case by simp
  1358   next
  1359     case insert
  1360     thus ?case using add_mono by fastsimp
  1361   qed
  1362 next
  1363   case False
  1364   thus ?thesis
  1365     by (simp add: setsum_def)
  1366 qed
  1367 
  1368 lemma setsum_strict_mono:
  1369   fixes f :: "'a \<Rightarrow> 'b::{pordered_cancel_ab_semigroup_add,comm_monoid_add}"
  1370   assumes "finite A"  "A \<noteq> {}"
  1371     and "!!x. x:A \<Longrightarrow> f x < g x"
  1372   shows "setsum f A < setsum g A"
  1373   using prems
  1374 proof (induct rule: finite_ne_induct)
  1375   case singleton thus ?case by simp
  1376 next
  1377   case insert thus ?case by (auto simp: add_strict_mono)
  1378 qed
  1379 
  1380 lemma setsum_negf:
  1381   "setsum (%x. - (f x)::'a::ab_group_add) A = - setsum f A"
  1382 proof (cases "finite A")
  1383   case True thus ?thesis by (induct set: finite) auto
  1384 next
  1385   case False thus ?thesis by (simp add: setsum_def)
  1386 qed
  1387 
  1388 lemma setsum_subtractf:
  1389   "setsum (%x. ((f x)::'a::ab_group_add) - g x) A =
  1390     setsum f A - setsum g A"
  1391 proof (cases "finite A")
  1392   case True thus ?thesis by (simp add: diff_minus setsum_addf setsum_negf)
  1393 next
  1394   case False thus ?thesis by (simp add: setsum_def)
  1395 qed
  1396 
  1397 lemma setsum_nonneg:
  1398   assumes nn: "\<forall>x\<in>A. (0::'a::{pordered_ab_semigroup_add,comm_monoid_add}) \<le> f x"
  1399   shows "0 \<le> setsum f A"
  1400 proof (cases "finite A")
  1401   case True thus ?thesis using nn
  1402   proof induct
  1403     case empty then show ?case by simp
  1404   next
  1405     case (insert x F)
  1406     then have "0 + 0 \<le> f x + setsum f F" by (blast intro: add_mono)
  1407     with insert show ?case by simp
  1408   qed
  1409 next
  1410   case False thus ?thesis by (simp add: setsum_def)
  1411 qed
  1412 
  1413 lemma setsum_nonpos:
  1414   assumes np: "\<forall>x\<in>A. f x \<le> (0::'a::{pordered_ab_semigroup_add,comm_monoid_add})"
  1415   shows "setsum f A \<le> 0"
  1416 proof (cases "finite A")
  1417   case True thus ?thesis using np
  1418   proof induct
  1419     case empty then show ?case by simp
  1420   next
  1421     case (insert x F)
  1422     then have "f x + setsum f F \<le> 0 + 0" by (blast intro: add_mono)
  1423     with insert show ?case by simp
  1424   qed
  1425 next
  1426   case False thus ?thesis by (simp add: setsum_def)
  1427 qed
  1428 
  1429 lemma setsum_mono2:
  1430 fixes f :: "'a \<Rightarrow> 'b :: {pordered_ab_semigroup_add_imp_le,comm_monoid_add}"
  1431 assumes fin: "finite B" and sub: "A \<subseteq> B" and nn: "\<And>b. b \<in> B-A \<Longrightarrow> 0 \<le> f b"
  1432 shows "setsum f A \<le> setsum f B"
  1433 proof -
  1434   have "setsum f A \<le> setsum f A + setsum f (B-A)"
  1435     by(simp add: add_increasing2[OF setsum_nonneg] nn Ball_def)
  1436   also have "\<dots> = setsum f (A \<union> (B-A))" using fin finite_subset[OF sub fin]
  1437     by (simp add:setsum_Un_disjoint del:Un_Diff_cancel)
  1438   also have "A \<union> (B-A) = B" using sub by blast
  1439   finally show ?thesis .
  1440 qed
  1441 
  1442 lemma setsum_mono3: "finite B ==> A <= B ==> 
  1443     ALL x: B - A. 
  1444       0 <= ((f x)::'a::{comm_monoid_add,pordered_ab_semigroup_add}) ==>
  1445         setsum f A <= setsum f B"
  1446   apply (subgoal_tac "setsum f B = setsum f A + setsum f (B - A)")
  1447   apply (erule ssubst)
  1448   apply (subgoal_tac "setsum f A + 0 <= setsum f A + setsum f (B - A)")
  1449   apply simp
  1450   apply (rule add_left_mono)
  1451   apply (erule setsum_nonneg)
  1452   apply (subst setsum_Un_disjoint [THEN sym])
  1453   apply (erule finite_subset, assumption)
  1454   apply (rule finite_subset)
  1455   prefer 2
  1456   apply assumption
  1457   apply auto
  1458   apply (rule setsum_cong)
  1459   apply auto
  1460 done
  1461 
  1462 lemma setsum_right_distrib: 
  1463   fixes f :: "'a => ('b::semiring_0)"
  1464   shows "r * setsum f A = setsum (%n. r * f n) A"
  1465 proof (cases "finite A")
  1466   case True
  1467   thus ?thesis
  1468   proof induct
  1469     case empty thus ?case by simp
  1470   next
  1471     case (insert x A) thus ?case by (simp add: right_distrib)
  1472   qed
  1473 next
  1474   case False thus ?thesis by (simp add: setsum_def)
  1475 qed
  1476 
  1477 lemma setsum_left_distrib:
  1478   "setsum f A * (r::'a::semiring_0) = (\<Sum>n\<in>A. f n * r)"
  1479 proof (cases "finite A")
  1480   case True
  1481   then show ?thesis
  1482   proof induct
  1483     case empty thus ?case by simp
  1484   next
  1485     case (insert x A) thus ?case by (simp add: left_distrib)
  1486   qed
  1487 next
  1488   case False thus ?thesis by (simp add: setsum_def)
  1489 qed
  1490 
  1491 lemma setsum_divide_distrib:
  1492   "setsum f A / (r::'a::field) = (\<Sum>n\<in>A. f n / r)"
  1493 proof (cases "finite A")
  1494   case True
  1495   then show ?thesis
  1496   proof induct
  1497     case empty thus ?case by simp
  1498   next
  1499     case (insert x A) thus ?case by (simp add: add_divide_distrib)
  1500   qed
  1501 next
  1502   case False thus ?thesis by (simp add: setsum_def)
  1503 qed
  1504 
  1505 lemma setsum_abs[iff]: 
  1506   fixes f :: "'a => ('b::pordered_ab_group_add_abs)"
  1507   shows "abs (setsum f A) \<le> setsum (%i. abs(f i)) A"
  1508 proof (cases "finite A")
  1509   case True
  1510   thus ?thesis
  1511   proof induct
  1512     case empty thus ?case by simp
  1513   next
  1514     case (insert x A)
  1515     thus ?case by (auto intro: abs_triangle_ineq order_trans)
  1516   qed
  1517 next
  1518   case False thus ?thesis by (simp add: setsum_def)
  1519 qed
  1520 
  1521 lemma setsum_abs_ge_zero[iff]: 
  1522   fixes f :: "'a => ('b::pordered_ab_group_add_abs)"
  1523   shows "0 \<le> setsum (%i. abs(f i)) A"
  1524 proof (cases "finite A")
  1525   case True
  1526   thus ?thesis
  1527   proof induct
  1528     case empty thus ?case by simp
  1529   next
  1530     case (insert x A) thus ?case by (auto simp: add_nonneg_nonneg)
  1531   qed
  1532 next
  1533   case False thus ?thesis by (simp add: setsum_def)
  1534 qed
  1535 
  1536 lemma abs_setsum_abs[simp]: 
  1537   fixes f :: "'a => ('b::pordered_ab_group_add_abs)"
  1538   shows "abs (\<Sum>a\<in>A. abs(f a)) = (\<Sum>a\<in>A. abs(f a))"
  1539 proof (cases "finite A")
  1540   case True
  1541   thus ?thesis
  1542   proof induct
  1543     case empty thus ?case by simp
  1544   next
  1545     case (insert a A)
  1546     hence "\<bar>\<Sum>a\<in>insert a A. \<bar>f a\<bar>\<bar> = \<bar>\<bar>f a\<bar> + (\<Sum>a\<in>A. \<bar>f a\<bar>)\<bar>" by simp
  1547     also have "\<dots> = \<bar>\<bar>f a\<bar> + \<bar>\<Sum>a\<in>A. \<bar>f a\<bar>\<bar>\<bar>"  using insert by simp
  1548     also have "\<dots> = \<bar>f a\<bar> + \<bar>\<Sum>a\<in>A. \<bar>f a\<bar>\<bar>"
  1549       by (simp del: abs_of_nonneg)
  1550     also have "\<dots> = (\<Sum>a\<in>insert a A. \<bar>f a\<bar>)" using insert by simp
  1551     finally show ?case .
  1552   qed
  1553 next
  1554   case False thus ?thesis by (simp add: setsum_def)
  1555 qed
  1556 
  1557 
  1558 text {* Commuting outer and inner summation *}
  1559 
  1560 lemma swap_inj_on:
  1561   "inj_on (%(i, j). (j, i)) (A \<times> B)"
  1562   by (unfold inj_on_def) fast
  1563 
  1564 lemma swap_product:
  1565   "(%(i, j). (j, i)) ` (A \<times> B) = B \<times> A"
  1566   by (simp add: split_def image_def) blast
  1567 
  1568 lemma setsum_commute:
  1569   "(\<Sum>i\<in>A. \<Sum>j\<in>B. f i j) = (\<Sum>j\<in>B. \<Sum>i\<in>A. f i j)"
  1570 proof (simp add: setsum_cartesian_product)
  1571   have "(\<Sum>(x,y) \<in> A <*> B. f x y) =
  1572     (\<Sum>(y,x) \<in> (%(i, j). (j, i)) ` (A \<times> B). f x y)"
  1573     (is "?s = _")
  1574     apply (simp add: setsum_reindex [where f = "%(i, j). (j, i)"] swap_inj_on)
  1575     apply (simp add: split_def)
  1576     done
  1577   also have "... = (\<Sum>(y,x)\<in>B \<times> A. f x y)"
  1578     (is "_ = ?t")
  1579     apply (simp add: swap_product)
  1580     done
  1581   finally show "?s = ?t" .
  1582 qed
  1583 
  1584 lemma setsum_product:
  1585   fixes f :: "'a => ('b::semiring_0)"
  1586   shows "setsum f A * setsum g B = (\<Sum>i\<in>A. \<Sum>j\<in>B. f i * g j)"
  1587   by (simp add: setsum_right_distrib setsum_left_distrib) (rule setsum_commute)
  1588 
  1589 
  1590 subsection {* Generalized product over a set *}
  1591 
  1592 definition setprod :: "('a => 'b) => 'a set => 'b::comm_monoid_mult"
  1593 where "setprod f A == if finite A then fold_image (op *) f 1 A else 1"
  1594 
  1595 abbreviation
  1596   Setprod  ("\<Prod>_" [1000] 999) where
  1597   "\<Prod>A == setprod (%x. x) A"
  1598 
  1599 syntax
  1600   "_setprod" :: "pttrn => 'a set => 'b => 'b::comm_monoid_mult"  ("(3PROD _:_. _)" [0, 51, 10] 10)
  1601 syntax (xsymbols)
  1602   "_setprod" :: "pttrn => 'a set => 'b => 'b::comm_monoid_mult"  ("(3\<Prod>_\<in>_. _)" [0, 51, 10] 10)
  1603 syntax (HTML output)
  1604   "_setprod" :: "pttrn => 'a set => 'b => 'b::comm_monoid_mult"  ("(3\<Prod>_\<in>_. _)" [0, 51, 10] 10)
  1605 
  1606 translations -- {* Beware of argument permutation! *}
  1607   "PROD i:A. b" == "CONST setprod (%i. b) A" 
  1608   "\<Prod>i\<in>A. b" == "CONST setprod (%i. b) A" 
  1609 
  1610 text{* Instead of @{term"\<Prod>x\<in>{x. P}. e"} we introduce the shorter
  1611  @{text"\<Prod>x|P. e"}. *}
  1612 
  1613 syntax
  1614   "_qsetprod" :: "pttrn \<Rightarrow> bool \<Rightarrow> 'a \<Rightarrow> 'a" ("(3PROD _ |/ _./ _)" [0,0,10] 10)
  1615 syntax (xsymbols)
  1616   "_qsetprod" :: "pttrn \<Rightarrow> bool \<Rightarrow> 'a \<Rightarrow> 'a" ("(3\<Prod>_ | (_)./ _)" [0,0,10] 10)
  1617 syntax (HTML output)
  1618   "_qsetprod" :: "pttrn \<Rightarrow> bool \<Rightarrow> 'a \<Rightarrow> 'a" ("(3\<Prod>_ | (_)./ _)" [0,0,10] 10)
  1619 
  1620 translations
  1621   "PROD x|P. t" => "CONST setprod (%x. t) {x. P}"
  1622   "\<Prod>x|P. t" => "CONST setprod (%x. t) {x. P}"
  1623 
  1624 
  1625 lemma setprod_empty [simp]: "setprod f {} = 1"
  1626 by (auto simp add: setprod_def)
  1627 
  1628 lemma setprod_insert [simp]: "[| finite A; a \<notin> A |] ==>
  1629     setprod f (insert a A) = f a * setprod f A"
  1630 by (simp add: setprod_def)
  1631 
  1632 lemma setprod_infinite [simp]: "~ finite A ==> setprod f A = 1"
  1633 by (simp add: setprod_def)
  1634 
  1635 lemma setprod_reindex:
  1636    "inj_on f B ==> setprod h (f ` B) = setprod (h \<circ> f) B"
  1637 by(auto simp: setprod_def fold_image_reindex dest!:finite_imageD)
  1638 
  1639 lemma setprod_reindex_id: "inj_on f B ==> setprod f B = setprod id (f ` B)"
  1640 by (auto simp add: setprod_reindex)
  1641 
  1642 lemma setprod_cong:
  1643   "A = B ==> (!!x. x:B ==> f x = g x) ==> setprod f A = setprod g B"
  1644 by(fastsimp simp: setprod_def intro: fold_image_cong)
  1645 
  1646 lemma strong_setprod_cong[cong]:
  1647   "A = B ==> (!!x. x:B =simp=> f x = g x) ==> setprod f A = setprod g B"
  1648 by(fastsimp simp: simp_implies_def setprod_def intro: fold_image_cong)
  1649 
  1650 lemma setprod_reindex_cong: "inj_on f A ==>
  1651     B = f ` A ==> g = h \<circ> f ==> setprod h B = setprod g A"
  1652 by (frule setprod_reindex, simp)
  1653 
  1654 lemma strong_setprod_reindex_cong: assumes i: "inj_on f A"
  1655   and B: "B = f ` A" and eq: "\<And>x. x \<in> A \<Longrightarrow> g x = (h \<circ> f) x"
  1656   shows "setprod h B = setprod g A"
  1657 proof-
  1658     have "setprod h B = setprod (h o f) A"
  1659       by (simp add: B setprod_reindex[OF i, of h])
  1660     then show ?thesis apply simp
  1661       apply (rule setprod_cong)
  1662       apply simp
  1663       by (simp add: eq)
  1664 qed
  1665 
  1666 lemma setprod_Un_one:  
  1667   assumes fS: "finite S" and fT: "finite T"
  1668   and I0: "\<forall>x \<in> S\<inter>T. f x = 1"
  1669   shows "setprod f (S \<union> T) = setprod f S  * setprod f T"
  1670   using fS fT
  1671   apply (simp add: setprod_def)
  1672   apply (rule fold_image_Un_one)
  1673   using I0 by auto
  1674 
  1675 
  1676 lemma setprod_1: "setprod (%i. 1) A = 1"
  1677 apply (case_tac "finite A")
  1678 apply (erule finite_induct, auto simp add: mult_ac)
  1679 done
  1680 
  1681 lemma setprod_1': "ALL a:F. f a = 1 ==> setprod f F = 1"
  1682 apply (subgoal_tac "setprod f F = setprod (%x. 1) F")
  1683 apply (erule ssubst, rule setprod_1)
  1684 apply (rule setprod_cong, auto)
  1685 done
  1686 
  1687 lemma setprod_Un_Int: "finite A ==> finite B
  1688     ==> setprod g (A Un B) * setprod g (A Int B) = setprod g A * setprod g B"
  1689 by(simp add: setprod_def fold_image_Un_Int[symmetric])
  1690 
  1691 lemma setprod_Un_disjoint: "finite A ==> finite B
  1692   ==> A Int B = {} ==> setprod g (A Un B) = setprod g A * setprod g B"
  1693 by (subst setprod_Un_Int [symmetric], auto)
  1694 
  1695 lemma setprod_mono_one_left: 
  1696   assumes fT: "finite T" and ST: "S \<subseteq> T"
  1697   and z: "\<forall>i \<in> T - S. f i = 1"
  1698   shows "setprod f S = setprod f T"
  1699 proof-
  1700   have eq: "T = S \<union> (T - S)" using ST by blast
  1701   have d: "S \<inter> (T - S) = {}" using ST by blast
  1702   from fT ST have f: "finite S" "finite (T - S)" by (auto intro: finite_subset)
  1703   show ?thesis
  1704   by (simp add: setprod_Un_disjoint[OF f d, unfolded eq[symmetric]] setprod_1'[OF z])
  1705 qed
  1706 
  1707 lemmas setprod_mono_one_right = setprod_mono_one_left [THEN sym]
  1708 
  1709 lemma setprod_delta: 
  1710   assumes fS: "finite S"
  1711   shows "setprod (\<lambda>k. if k=a then b k else 1) S = (if a \<in> S then b a else 1)"
  1712 proof-
  1713   let ?f = "(\<lambda>k. if k=a then b k else 1)"
  1714   {assume a: "a \<notin> S"
  1715     hence "\<forall> k\<in> S. ?f k = 1" by simp
  1716     hence ?thesis  using a by (simp add: setprod_1 cong add: setprod_cong) }
  1717   moreover 
  1718   {assume a: "a \<in> S"
  1719     let ?A = "S - {a}"
  1720     let ?B = "{a}"
  1721     have eq: "S = ?A \<union> ?B" using a by blast 
  1722     have dj: "?A \<inter> ?B = {}" by simp
  1723     from fS have fAB: "finite ?A" "finite ?B" by auto  
  1724     have fA1: "setprod ?f ?A = 1" apply (rule setprod_1') by auto
  1725     have "setprod ?f ?A * setprod ?f ?B = setprod ?f S"
  1726       using setprod_Un_disjoint[OF fAB dj, of ?f, unfolded eq[symmetric]]
  1727       by simp
  1728     then have ?thesis  using a by (simp add: fA1 cong add: setprod_cong cong del: if_weak_cong)}
  1729   ultimately show ?thesis by blast
  1730 qed
  1731 
  1732 lemma setprod_delta': 
  1733   assumes fS: "finite S" shows 
  1734   "setprod (\<lambda>k. if a = k then b k else 1) S = 
  1735      (if a\<in> S then b a else 1)"
  1736   using setprod_delta[OF fS, of a b, symmetric] 
  1737   by (auto intro: setprod_cong)
  1738 
  1739 
  1740 lemma setprod_UN_disjoint:
  1741     "finite I ==> (ALL i:I. finite (A i)) ==>
  1742         (ALL i:I. ALL j:I. i \<noteq> j --> A i Int A j = {}) ==>
  1743       setprod f (UNION I A) = setprod (%i. setprod f (A i)) I"
  1744 by(simp add: setprod_def fold_image_UN_disjoint cong: setprod_cong)
  1745 
  1746 lemma setprod_Union_disjoint:
  1747   "[| (ALL A:C. finite A);
  1748       (ALL A:C. ALL B:C. A \<noteq> B --> A Int B = {}) |] 
  1749    ==> setprod f (Union C) = setprod (setprod f) C"
  1750 apply (cases "finite C") 
  1751  prefer 2 apply (force dest: finite_UnionD simp add: setprod_def)
  1752   apply (frule setprod_UN_disjoint [of C id f])
  1753  apply (unfold Union_def id_def, assumption+)
  1754 done
  1755 
  1756 lemma setprod_Sigma: "finite A ==> ALL x:A. finite (B x) ==>
  1757     (\<Prod>x\<in>A. (\<Prod>y\<in> B x. f x y)) =
  1758     (\<Prod>(x,y)\<in>(SIGMA x:A. B x). f x y)"
  1759 by(simp add:setprod_def fold_image_Sigma split_def cong:setprod_cong)
  1760 
  1761 text{*Here we can eliminate the finiteness assumptions, by cases.*}
  1762 lemma setprod_cartesian_product: 
  1763      "(\<Prod>x\<in>A. (\<Prod>y\<in> B. f x y)) = (\<Prod>(x,y)\<in>(A <*> B). f x y)"
  1764 apply (cases "finite A") 
  1765  apply (cases "finite B") 
  1766   apply (simp add: setprod_Sigma)
  1767  apply (cases "A={}", simp)
  1768  apply (simp add: setprod_1) 
  1769 apply (auto simp add: setprod_def
  1770             dest: finite_cartesian_productD1 finite_cartesian_productD2) 
  1771 done
  1772 
  1773 lemma setprod_timesf:
  1774      "setprod (%x. f x * g x) A = (setprod f A * setprod g A)"
  1775 by(simp add:setprod_def fold_image_distrib)
  1776 
  1777 
  1778 subsubsection {* Properties in more restricted classes of structures *}
  1779 
  1780 lemma setprod_eq_1_iff [simp]:
  1781   "finite F ==> (setprod f F = 1) = (ALL a:F. f a = (1::nat))"
  1782 by (induct set: finite) auto
  1783 
  1784 lemma setprod_zero:
  1785      "finite A ==> EX x: A. f x = (0::'a::comm_semiring_1) ==> setprod f A = 0"
  1786 apply (induct set: finite, force, clarsimp)
  1787 apply (erule disjE, auto)
  1788 done
  1789 
  1790 lemma setprod_nonneg [rule_format]:
  1791    "(ALL x: A. (0::'a::ordered_semidom) \<le> f x) --> 0 \<le> setprod f A"
  1792 by (cases "finite A", induct set: finite, simp_all add: mult_nonneg_nonneg)
  1793 
  1794 lemma setprod_pos [rule_format]: "(ALL x: A. (0::'a::ordered_semidom) < f x)
  1795   --> 0 < setprod f A"
  1796 by (cases "finite A", induct set: finite, simp_all add: mult_pos_pos)
  1797 
  1798 lemma setprod_nonzero [rule_format]:
  1799   "(ALL x y. (x::'a::comm_semiring_1) * y = 0 --> x = 0 | y = 0) ==>
  1800     finite A ==> (ALL x: A. f x \<noteq> (0::'a)) --> setprod f A \<noteq> 0"
  1801 by (erule finite_induct, auto)
  1802 
  1803 lemma setprod_zero_eq:
  1804     "(ALL x y. (x::'a::comm_semiring_1) * y = 0 --> x = 0 | y = 0) ==>
  1805      finite A ==> (setprod f A = (0::'a)) = (EX x: A. f x = 0)"
  1806 by (insert setprod_zero [of A f] setprod_nonzero [of A f], blast)
  1807 
  1808 lemma setprod_nonzero_field:
  1809     "finite A ==> (ALL x: A. f x \<noteq> (0::'a::idom)) ==> setprod f A \<noteq> 0"
  1810 by (rule setprod_nonzero, auto)
  1811 
  1812 lemma setprod_zero_eq_field:
  1813     "finite A ==> (setprod f A = (0::'a::idom)) = (EX x: A. f x = 0)"
  1814 by (rule setprod_zero_eq, auto)
  1815 
  1816 lemma setprod_Un: "finite A ==> finite B ==> (ALL x: A Int B. f x \<noteq> 0) ==>
  1817   (setprod f (A Un B) :: 'a ::{field})
  1818    = setprod f A * setprod f B / setprod f (A Int B)"
  1819 apply (subst setprod_Un_Int [symmetric], auto)
  1820 apply (subgoal_tac "finite (A Int B)")
  1821 apply (frule setprod_nonzero_field [of "A Int B" f], assumption)
  1822 apply (subst times_divide_eq_right [THEN sym], auto)
  1823 done
  1824 
  1825 lemma setprod_diff1: "finite A ==> f a \<noteq> 0 ==>
  1826   (setprod f (A - {a}) :: 'a :: {field}) =
  1827   (if a:A then setprod f A / f a else setprod f A)"
  1828 by (erule finite_induct) (auto simp add: insert_Diff_if)
  1829 
  1830 lemma setprod_inversef: "finite A ==>
  1831   ALL x: A. f x \<noteq> (0::'a::{field,division_by_zero}) ==>
  1832   setprod (inverse \<circ> f) A = inverse (setprod f A)"
  1833 by (erule finite_induct) auto
  1834 
  1835 lemma setprod_dividef:
  1836    "[|finite A;
  1837       \<forall>x \<in> A. g x \<noteq> (0::'a::{field,division_by_zero})|]
  1838     ==> setprod (%x. f x / g x) A = setprod f A / setprod g A"
  1839 apply (subgoal_tac
  1840          "setprod (%x. f x / g x) A = setprod (%x. f x * (inverse \<circ> g) x) A")
  1841 apply (erule ssubst)
  1842 apply (subst divide_inverse)
  1843 apply (subst setprod_timesf)
  1844 apply (subst setprod_inversef, assumption+, rule refl)
  1845 apply (rule setprod_cong, rule refl)
  1846 apply (subst divide_inverse, auto)
  1847 done
  1848 
  1849 lemma setprod_dvd_setprod [rule_format]: 
  1850     "(ALL x : A. f x dvd g x) \<longrightarrow> setprod f A dvd setprod g A"
  1851   apply (cases "finite A")
  1852   apply (induct set: finite)
  1853   apply (auto simp add: dvd_def)
  1854   apply (rule_tac x = "k * ka" in exI)
  1855   apply (simp add: algebra_simps)
  1856 done
  1857 
  1858 lemma setprod_dvd_setprod_subset:
  1859   "finite B \<Longrightarrow> A <= B \<Longrightarrow> setprod f A dvd setprod f B"
  1860   apply (subgoal_tac "setprod f B = setprod f A * setprod f (B - A)")
  1861   apply (unfold dvd_def, blast)
  1862   apply (subst setprod_Un_disjoint [symmetric])
  1863   apply (auto elim: finite_subset intro: setprod_cong)
  1864 done
  1865 
  1866 lemma setprod_dvd_setprod_subset2:
  1867   "finite B \<Longrightarrow> A <= B \<Longrightarrow> ALL x : A. (f x::'a::comm_semiring_1) dvd g x \<Longrightarrow> 
  1868       setprod f A dvd setprod g B"
  1869   apply (rule dvd_trans)
  1870   apply (rule setprod_dvd_setprod, erule (1) bspec)
  1871   apply (erule (1) setprod_dvd_setprod_subset)
  1872 done
  1873 
  1874 lemma dvd_setprod: "finite A \<Longrightarrow> i:A \<Longrightarrow> 
  1875     (f i ::'a::comm_semiring_1) dvd setprod f A"
  1876 by (induct set: finite) (auto intro: dvd_mult)
  1877 
  1878 lemma dvd_setsum [rule_format]: "(ALL i : A. d dvd f i) \<longrightarrow> 
  1879     (d::'a::comm_semiring_1) dvd (SUM x : A. f x)"
  1880   apply (cases "finite A")
  1881   apply (induct set: finite)
  1882   apply auto
  1883 done
  1884 
  1885 
  1886 subsection {* Finite cardinality *}
  1887 
  1888 text {* This definition, although traditional, is ugly to work with:
  1889 @{text "card A == LEAST n. EX f. A = {f i | i. i < n}"}.
  1890 But now that we have @{text setsum} things are easy:
  1891 *}
  1892 
  1893 definition card :: "'a set \<Rightarrow> nat"
  1894 where "card A = setsum (\<lambda>x. 1) A"
  1895 
  1896 lemma card_empty [simp]: "card {} = 0"
  1897 by (simp add: card_def)
  1898 
  1899 lemma card_infinite [simp]: "~ finite A ==> card A = 0"
  1900 by (simp add: card_def)
  1901 
  1902 lemma card_eq_setsum: "card A = setsum (%x. 1) A"
  1903 by (simp add: card_def)
  1904 
  1905 lemma card_insert_disjoint [simp]:
  1906   "finite A ==> x \<notin> A ==> card (insert x A) = Suc(card A)"
  1907 by(simp add: card_def)
  1908 
  1909 lemma card_insert_if:
  1910   "finite A ==> card (insert x A) = (if x:A then card A else Suc(card(A)))"
  1911 by (simp add: insert_absorb)
  1912 
  1913 lemma card_0_eq [simp,noatp]: "finite A ==> (card A = 0) = (A = {})"
  1914 apply auto
  1915 apply (drule_tac a = x in mk_disjoint_insert, clarify, auto)
  1916 done
  1917 
  1918 lemma card_eq_0_iff: "(card A = 0) = (A = {} | ~ finite A)"
  1919 by auto
  1920 
  1921 
  1922 lemma card_Suc_Diff1: "finite A ==> x: A ==> Suc (card (A - {x})) = card A"
  1923 apply(rule_tac t = A in insert_Diff [THEN subst], assumption)
  1924 apply(simp del:insert_Diff_single)
  1925 done
  1926 
  1927 lemma card_Diff_singleton:
  1928   "finite A ==> x: A ==> card (A - {x}) = card A - 1"
  1929 by (simp add: card_Suc_Diff1 [symmetric])
  1930 
  1931 lemma card_Diff_singleton_if:
  1932   "finite A ==> card (A-{x}) = (if x : A then card A - 1 else card A)"
  1933 by (simp add: card_Diff_singleton)
  1934 
  1935 lemma card_Diff_insert[simp]:
  1936 assumes "finite A" and "a:A" and "a ~: B"
  1937 shows "card(A - insert a B) = card(A - B) - 1"
  1938 proof -
  1939   have "A - insert a B = (A - B) - {a}" using assms by blast
  1940   then show ?thesis using assms by(simp add:card_Diff_singleton)
  1941 qed
  1942 
  1943 lemma card_insert: "finite A ==> card (insert x A) = Suc (card (A - {x}))"
  1944 by (simp add: card_insert_if card_Suc_Diff1 del:card_Diff_insert)
  1945 
  1946 lemma card_insert_le: "finite A ==> card A <= card (insert x A)"
  1947 by (simp add: card_insert_if)
  1948 
  1949 lemma card_mono: "\<lbrakk> finite B; A \<subseteq> B \<rbrakk> \<Longrightarrow> card A \<le> card B"
  1950 by (simp add: card_def setsum_mono2)
  1951 
  1952 lemma card_seteq: "finite B ==> (!!A. A <= B ==> card B <= card A ==> A = B)"
  1953 apply (induct set: finite, simp, clarify)
  1954 apply (subgoal_tac "finite A & A - {x} <= F")
  1955  prefer 2 apply (blast intro: finite_subset, atomize)
  1956 apply (drule_tac x = "A - {x}" in spec)
  1957 apply (simp add: card_Diff_singleton_if split add: split_if_asm)
  1958 apply (case_tac "card A", auto)
  1959 done
  1960 
  1961 lemma psubset_card_mono: "finite B ==> A < B ==> card A < card B"
  1962 apply (simp add: psubset_eq linorder_not_le [symmetric])
  1963 apply (blast dest: card_seteq)
  1964 done
  1965 
  1966 lemma card_Un_Int: "finite A ==> finite B
  1967     ==> card A + card B = card (A Un B) + card (A Int B)"
  1968 by(simp add:card_def setsum_Un_Int)
  1969 
  1970 lemma card_Un_disjoint: "finite A ==> finite B
  1971     ==> A Int B = {} ==> card (A Un B) = card A + card B"
  1972 by (simp add: card_Un_Int)
  1973 
  1974 lemma card_Diff_subset:
  1975   "finite B ==> B <= A ==> card (A - B) = card A - card B"
  1976 by(simp add:card_def setsum_diff_nat)
  1977 
  1978 lemma card_Diff1_less: "finite A ==> x: A ==> card (A - {x}) < card A"
  1979 apply (rule Suc_less_SucD)
  1980 apply (simp add: card_Suc_Diff1 del:card_Diff_insert)
  1981 done
  1982 
  1983 lemma card_Diff2_less:
  1984   "finite A ==> x: A ==> y: A ==> card (A - {x} - {y}) < card A"
  1985 apply (case_tac "x = y")
  1986  apply (simp add: card_Diff1_less del:card_Diff_insert)
  1987 apply (rule less_trans)
  1988  prefer 2 apply (auto intro!: card_Diff1_less simp del:card_Diff_insert)
  1989 done
  1990 
  1991 lemma card_Diff1_le: "finite A ==> card (A - {x}) <= card A"
  1992 apply (case_tac "x : A")
  1993  apply (simp_all add: card_Diff1_less less_imp_le)
  1994 done
  1995 
  1996 lemma card_psubset: "finite B ==> A \<subseteq> B ==> card A < card B ==> A < B"
  1997 by (erule psubsetI, blast)
  1998 
  1999 lemma insert_partition:
  2000   "\<lbrakk> x \<notin> F; \<forall>c1 \<in> insert x F. \<forall>c2 \<in> insert x F. c1 \<noteq> c2 \<longrightarrow> c1 \<inter> c2 = {} \<rbrakk>
  2001   \<Longrightarrow> x \<inter> \<Union> F = {}"
  2002 by auto
  2003 
  2004 text{* main cardinality theorem *}
  2005 lemma card_partition [rule_format]:
  2006   "finite C ==>
  2007      finite (\<Union> C) -->
  2008      (\<forall>c\<in>C. card c = k) -->
  2009      (\<forall>c1 \<in> C. \<forall>c2 \<in> C. c1 \<noteq> c2 --> c1 \<inter> c2 = {}) -->
  2010      k * card(C) = card (\<Union> C)"
  2011 apply (erule finite_induct, simp)
  2012 apply (simp add: card_insert_disjoint card_Un_disjoint insert_partition 
  2013        finite_subset [of _ "\<Union> (insert x F)"])
  2014 done
  2015 
  2016 
  2017 text{*The form of a finite set of given cardinality*}
  2018 
  2019 lemma card_eq_SucD:
  2020 assumes "card A = Suc k"
  2021 shows "\<exists>b B. A = insert b B & b \<notin> B & card B = k & (k=0 \<longrightarrow> B={})"
  2022 proof -
  2023   have fin: "finite A" using assms by (auto intro: ccontr)
  2024   moreover have "card A \<noteq> 0" using assms by auto
  2025   ultimately obtain b where b: "b \<in> A" by auto
  2026   show ?thesis
  2027   proof (intro exI conjI)
  2028     show "A = insert b (A-{b})" using b by blast
  2029     show "b \<notin> A - {b}" by blast
  2030     show "card (A - {b}) = k" and "k = 0 \<longrightarrow> A - {b} = {}"
  2031       using assms b fin by(fastsimp dest:mk_disjoint_insert)+
  2032   qed
  2033 qed
  2034 
  2035 lemma card_Suc_eq:
  2036   "(card A = Suc k) =
  2037    (\<exists>b B. A = insert b B & b \<notin> B & card B = k & (k=0 \<longrightarrow> B={}))"
  2038 apply(rule iffI)
  2039  apply(erule card_eq_SucD)
  2040 apply(auto)
  2041 apply(subst card_insert)
  2042  apply(auto intro:ccontr)
  2043 done
  2044 
  2045 lemma setsum_constant [simp]: "(\<Sum>x \<in> A. y) = of_nat(card A) * y"
  2046 apply (cases "finite A")
  2047 apply (erule finite_induct)
  2048 apply (auto simp add: algebra_simps)
  2049 done
  2050 
  2051 lemma setprod_constant: "finite A ==> (\<Prod>x\<in> A. (y::'a::{recpower, comm_monoid_mult})) = y^(card A)"
  2052 apply (erule finite_induct)
  2053 apply (auto simp add: power_Suc)
  2054 done
  2055 
  2056 lemma setprod_gen_delta:
  2057   assumes fS: "finite S"
  2058   shows "setprod (\<lambda>k. if k=a then b k else c) S = (if a \<in> S then (b a ::'a::{comm_monoid_mult, recpower}) * c^ (card S - 1) else c^ card S)"
  2059 proof-
  2060   let ?f = "(\<lambda>k. if k=a then b k else c)"
  2061   {assume a: "a \<notin> S"
  2062     hence "\<forall> k\<in> S. ?f k = c" by simp
  2063     hence ?thesis  using a setprod_constant[OF fS, of c] by (simp add: setprod_1 cong add: setprod_cong) }
  2064   moreover 
  2065   {assume a: "a \<in> S"
  2066     let ?A = "S - {a}"
  2067     let ?B = "{a}"
  2068     have eq: "S = ?A \<union> ?B" using a by blast 
  2069     have dj: "?A \<inter> ?B = {}" by simp
  2070     from fS have fAB: "finite ?A" "finite ?B" by auto  
  2071     have fA0:"setprod ?f ?A = setprod (\<lambda>i. c) ?A"
  2072       apply (rule setprod_cong) by auto
  2073     have cA: "card ?A = card S - 1" using fS a by auto
  2074     have fA1: "setprod ?f ?A = c ^ card ?A"  unfolding fA0 apply (rule setprod_constant) using fS by auto
  2075     have "setprod ?f ?A * setprod ?f ?B = setprod ?f S"
  2076       using setprod_Un_disjoint[OF fAB dj, of ?f, unfolded eq[symmetric]]
  2077       by simp
  2078     then have ?thesis using a cA
  2079       by (simp add: fA1 ring_simps cong add: setprod_cong cong del: if_weak_cong)}
  2080   ultimately show ?thesis by blast
  2081 qed
  2082 
  2083 
  2084 lemma setsum_bounded:
  2085   assumes le: "\<And>i. i\<in>A \<Longrightarrow> f i \<le> (K::'a::{semiring_1, pordered_ab_semigroup_add})"
  2086   shows "setsum f A \<le> of_nat(card A) * K"
  2087 proof (cases "finite A")
  2088   case True
  2089   thus ?thesis using le setsum_mono[where K=A and g = "%x. K"] by simp
  2090 next
  2091   case False thus ?thesis by (simp add: setsum_def)
  2092 qed
  2093 
  2094 
  2095 subsubsection {* Cardinality of unions *}
  2096 
  2097 lemma card_UN_disjoint:
  2098   "finite I ==> (ALL i:I. finite (A i)) ==>
  2099    (ALL i:I. ALL j:I. i \<noteq> j --> A i Int A j = {})
  2100    ==> card (UNION I A) = (\<Sum>i\<in>I. card(A i))"
  2101 apply (simp add: card_def del: setsum_constant)
  2102 apply (subgoal_tac
  2103          "setsum (%i. card (A i)) I = setsum (%i. (setsum (%x. 1) (A i))) I")
  2104 apply (simp add: setsum_UN_disjoint del: setsum_constant)
  2105 apply (simp cong: setsum_cong)
  2106 done
  2107 
  2108 lemma card_Union_disjoint:
  2109   "finite C ==> (ALL A:C. finite A) ==>
  2110    (ALL A:C. ALL B:C. A \<noteq> B --> A Int B = {})
  2111    ==> card (Union C) = setsum card C"
  2112 apply (frule card_UN_disjoint [of C id])
  2113 apply (unfold Union_def id_def, assumption+)
  2114 done
  2115 
  2116 
  2117 subsubsection {* Cardinality of image *}
  2118 
  2119 text{*The image of a finite set can be expressed using @{term fold_image}.*}
  2120 lemma image_eq_fold_image:
  2121   "finite A ==> f ` A = fold_image (op Un) (%x. {f x}) {} A"
  2122 proof (induct rule: finite_induct)
  2123   case empty then show ?case by simp
  2124 next
  2125   interpret ab_semigroup_mult "op Un"
  2126     proof qed auto
  2127   case insert 
  2128   then show ?case by simp
  2129 qed
  2130 
  2131 lemma card_image_le: "finite A ==> card (f ` A) <= card A"
  2132 apply (induct set: finite)
  2133  apply simp
  2134 apply (simp add: le_SucI finite_imageI card_insert_if)
  2135 done
  2136 
  2137 lemma card_image: "inj_on f A ==> card (f ` A) = card A"
  2138 by(simp add:card_def setsum_reindex o_def del:setsum_constant)
  2139 
  2140 lemma endo_inj_surj: "finite A ==> f ` A \<subseteq> A ==> inj_on f A ==> f ` A = A"
  2141 by (simp add: card_seteq card_image)
  2142 
  2143 lemma eq_card_imp_inj_on:
  2144   "[| finite A; card(f ` A) = card A |] ==> inj_on f A"
  2145 apply (induct rule:finite_induct)
  2146 apply simp
  2147 apply(frule card_image_le[where f = f])
  2148 apply(simp add:card_insert_if split:if_splits)
  2149 done
  2150 
  2151 lemma inj_on_iff_eq_card:
  2152   "finite A ==> inj_on f A = (card(f ` A) = card A)"
  2153 by(blast intro: card_image eq_card_imp_inj_on)
  2154 
  2155 
  2156 lemma card_inj_on_le:
  2157   "[|inj_on f A; f ` A \<subseteq> B; finite B |] ==> card A \<le> card B"
  2158 apply (subgoal_tac "finite A") 
  2159  apply (force intro: card_mono simp add: card_image [symmetric])
  2160 apply (blast intro: finite_imageD dest: finite_subset) 
  2161 done
  2162 
  2163 lemma card_bij_eq:
  2164   "[|inj_on f A; f ` A \<subseteq> B; inj_on g B; g ` B \<subseteq> A;
  2165      finite A; finite B |] ==> card A = card B"
  2166 by (auto intro: le_anti_sym card_inj_on_le)
  2167 
  2168 
  2169 subsubsection {* Cardinality of products *}
  2170 
  2171 (*
  2172 lemma SigmaI_insert: "y \<notin> A ==>
  2173   (SIGMA x:(insert y A). B x) = (({y} <*> (B y)) \<union> (SIGMA x: A. B x))"
  2174   by auto
  2175 *)
  2176 
  2177 lemma card_SigmaI [simp]:
  2178   "\<lbrakk> finite A; ALL a:A. finite (B a) \<rbrakk>
  2179   \<Longrightarrow> card (SIGMA x: A. B x) = (\<Sum>a\<in>A. card (B a))"
  2180 by(simp add:card_def setsum_Sigma del:setsum_constant)
  2181 
  2182 lemma card_cartesian_product: "card (A <*> B) = card(A) * card(B)"
  2183 apply (cases "finite A") 
  2184 apply (cases "finite B") 
  2185 apply (auto simp add: card_eq_0_iff
  2186             dest: finite_cartesian_productD1 finite_cartesian_productD2)
  2187 done
  2188 
  2189 lemma card_cartesian_product_singleton:  "card({x} <*> A) = card(A)"
  2190 by (simp add: card_cartesian_product)
  2191 
  2192 
  2193 subsubsection {* Cardinality of sums *}
  2194 
  2195 lemma card_Plus:
  2196   assumes "finite A" and "finite B"
  2197   shows "card (A <+> B) = card A + card B"
  2198 proof -
  2199   have "Inl`A \<inter> Inr`B = {}" by fast
  2200   with assms show ?thesis
  2201     unfolding Plus_def
  2202     by (simp add: card_Un_disjoint card_image)
  2203 qed
  2204 
  2205 
  2206 subsubsection {* Cardinality of the Powerset *}
  2207 
  2208 lemma card_Pow: "finite A ==> card (Pow A) = Suc (Suc 0) ^ card A"  (* FIXME numeral 2 (!?) *)
  2209 apply (induct set: finite)
  2210  apply (simp_all add: Pow_insert)
  2211 apply (subst card_Un_disjoint, blast)
  2212   apply (blast intro: finite_imageI, blast)
  2213 apply (subgoal_tac "inj_on (insert x) (Pow F)")
  2214  apply (simp add: card_image Pow_insert)
  2215 apply (unfold inj_on_def)
  2216 apply (blast elim!: equalityE)
  2217 done
  2218 
  2219 text {* Relates to equivalence classes.  Based on a theorem of F. Kammüller.  *}
  2220 
  2221 lemma dvd_partition:
  2222   "finite (Union C) ==>
  2223     ALL c : C. k dvd card c ==>
  2224     (ALL c1: C. ALL c2: C. c1 \<noteq> c2 --> c1 Int c2 = {}) ==>
  2225   k dvd card (Union C)"
  2226 apply(frule finite_UnionD)
  2227 apply(rotate_tac -1)
  2228 apply (induct set: finite, simp_all, clarify)
  2229 apply (subst card_Un_disjoint)
  2230    apply (auto simp add: dvd_add disjoint_eq_subset_Compl)
  2231 done
  2232 
  2233 
  2234 subsubsection {* Relating injectivity and surjectivity *}
  2235 
  2236 lemma finite_surj_inj: "finite(A) \<Longrightarrow> A <= f`A \<Longrightarrow> inj_on f A"
  2237 apply(rule eq_card_imp_inj_on, assumption)
  2238 apply(frule finite_imageI)
  2239 apply(drule (1) card_seteq)
  2240  apply(erule card_image_le)
  2241 apply simp
  2242 done
  2243 
  2244 lemma finite_UNIV_surj_inj: fixes f :: "'a \<Rightarrow> 'a"
  2245 shows "finite(UNIV:: 'a set) \<Longrightarrow> surj f \<Longrightarrow> inj f"
  2246 by (blast intro: finite_surj_inj subset_UNIV dest:surj_range)
  2247 
  2248 lemma finite_UNIV_inj_surj: fixes f :: "'a \<Rightarrow> 'a"
  2249 shows "finite(UNIV:: 'a set) \<Longrightarrow> inj f \<Longrightarrow> surj f"
  2250 by(fastsimp simp:surj_def dest!: endo_inj_surj)
  2251 
  2252 corollary infinite_UNIV_nat: "~finite(UNIV::nat set)"
  2253 proof
  2254   assume "finite(UNIV::nat set)"
  2255   with finite_UNIV_inj_surj[of Suc]
  2256   show False by simp (blast dest: Suc_neq_Zero surjD)
  2257 qed
  2258 
  2259 lemma infinite_UNIV_char_0:
  2260   "\<not> finite (UNIV::'a::semiring_char_0 set)"
  2261 proof
  2262   assume "finite (UNIV::'a set)"
  2263   with subset_UNIV have "finite (range of_nat::'a set)"
  2264     by (rule finite_subset)
  2265   moreover have "inj (of_nat::nat \<Rightarrow> 'a)"
  2266     by (simp add: inj_on_def)
  2267   ultimately have "finite (UNIV::nat set)"
  2268     by (rule finite_imageD)
  2269   then show "False"
  2270     by (simp add: infinite_UNIV_nat)
  2271 qed
  2272 
  2273 subsection{* A fold functional for non-empty sets *}
  2274 
  2275 text{* Does not require start value. *}
  2276 
  2277 inductive
  2278   fold1Set :: "('a => 'a => 'a) => 'a set => 'a => bool"
  2279   for f :: "'a => 'a => 'a"
  2280 where
  2281   fold1Set_insertI [intro]:
  2282    "\<lbrakk> fold_graph f a A x; a \<notin> A \<rbrakk> \<Longrightarrow> fold1Set f (insert a A) x"
  2283 
  2284 constdefs
  2285   fold1 :: "('a => 'a => 'a) => 'a set => 'a"
  2286   "fold1 f A == THE x. fold1Set f A x"
  2287 
  2288 lemma fold1Set_nonempty:
  2289   "fold1Set f A x \<Longrightarrow> A \<noteq> {}"
  2290 by(erule fold1Set.cases, simp_all)
  2291 
  2292 inductive_cases empty_fold1SetE [elim!]: "fold1Set f {} x"
  2293 
  2294 inductive_cases insert_fold1SetE [elim!]: "fold1Set f (insert a X) x"
  2295 
  2296 
  2297 lemma fold1Set_sing [iff]: "(fold1Set f {a} b) = (a = b)"
  2298 by (blast intro: fold_graph.intros elim: fold_graph.cases)
  2299 
  2300 lemma fold1_singleton [simp]: "fold1 f {a} = a"
  2301 by (unfold fold1_def) blast
  2302 
  2303 lemma finite_nonempty_imp_fold1Set:
  2304   "\<lbrakk> finite A; A \<noteq> {} \<rbrakk> \<Longrightarrow> EX x. fold1Set f A x"
  2305 apply (induct A rule: finite_induct)
  2306 apply (auto dest: finite_imp_fold_graph [of _ f])
  2307 done
  2308 
  2309 text{*First, some lemmas about @{const fold_graph}.*}
  2310 
  2311 context ab_semigroup_mult
  2312 begin
  2313 
  2314 lemma fun_left_comm: "fun_left_comm(op *)"
  2315 by unfold_locales (simp add: mult_ac)
  2316 
  2317 lemma fold_graph_insert_swap:
  2318 assumes fold: "fold_graph times (b::'a) A y" and "b \<notin> A"
  2319 shows "fold_graph times z (insert b A) (z * y)"
  2320 proof -
  2321   interpret fun_left_comm "op *::'a \<Rightarrow> 'a \<Rightarrow> 'a" by (rule fun_left_comm)
  2322 from assms show ?thesis
  2323 proof (induct rule: fold_graph.induct)
  2324   case emptyI thus ?case by (force simp add: fold_insert_aux mult_commute)
  2325 next
  2326   case (insertI x A y)
  2327     have "fold_graph times z (insert x (insert b A)) (x * (z * y))"
  2328       using insertI by force  --{*how does @{term id} get unfolded?*}
  2329     thus ?case by (simp add: insert_commute mult_ac)
  2330 qed
  2331 qed
  2332 
  2333 lemma fold_graph_permute_diff:
  2334 assumes fold: "fold_graph times b A x"
  2335 shows "!!a. \<lbrakk>a \<in> A; b \<notin> A\<rbrakk> \<Longrightarrow> fold_graph times a (insert b (A-{a})) x"
  2336 using fold
  2337 proof (induct rule: fold_graph.induct)
  2338   case emptyI thus ?case by simp
  2339 next
  2340   case (insertI x A y)
  2341   have "a = x \<or> a \<in> A" using insertI by simp
  2342   thus ?case
  2343   proof
  2344     assume "a = x"
  2345     with insertI show ?thesis
  2346       by (simp add: id_def [symmetric], blast intro: fold_graph_insert_swap)
  2347   next
  2348     assume ainA: "a \<in> A"
  2349     hence "fold_graph times a (insert x (insert b (A - {a}))) (x * y)"
  2350       using insertI by force
  2351     moreover
  2352     have "insert x (insert b (A - {a})) = insert b (insert x A - {a})"
  2353       using ainA insertI by blast
  2354     ultimately show ?thesis by simp
  2355   qed
  2356 qed
  2357 
  2358 lemma fold1_eq_fold:
  2359 assumes "finite A" "a \<notin> A" shows "fold1 times (insert a A) = fold times a A"
  2360 proof -
  2361   interpret fun_left_comm "op *::'a \<Rightarrow> 'a \<Rightarrow> 'a" by (rule fun_left_comm)
  2362   from assms show ?thesis
  2363 apply (simp add: fold1_def fold_def)
  2364 apply (rule the_equality)
  2365 apply (best intro: fold_graph_determ theI dest: finite_imp_fold_graph [of _ times])
  2366 apply (rule sym, clarify)
  2367 apply (case_tac "Aa=A")
  2368  apply (best intro: the_equality fold_graph_determ)
  2369 apply (subgoal_tac "fold_graph times a A x")
  2370  apply (best intro: the_equality fold_graph_determ)
  2371 apply (subgoal_tac "insert aa (Aa - {a}) = A")
  2372  prefer 2 apply (blast elim: equalityE)
  2373 apply (auto dest: fold_graph_permute_diff [where a=a])
  2374 done
  2375 qed
  2376 
  2377 lemma nonempty_iff: "(A \<noteq> {}) = (\<exists>x B. A = insert x B & x \<notin> B)"
  2378 apply safe
  2379  apply simp
  2380  apply (drule_tac x=x in spec)
  2381  apply (drule_tac x="A-{x}" in spec, auto)
  2382 done
  2383 
  2384 lemma fold1_insert:
  2385   assumes nonempty: "A \<noteq> {}" and A: "finite A" "x \<notin> A"
  2386   shows "fold1 times (insert x A) = x * fold1 times A"
  2387 proof -
  2388   interpret fun_left_comm "op *::'a \<Rightarrow> 'a \<Rightarrow> 'a" by (rule fun_left_comm)
  2389   from nonempty obtain a A' where "A = insert a A' & a ~: A'"
  2390     by (auto simp add: nonempty_iff)
  2391   with A show ?thesis
  2392     by (simp add: insert_commute [of x] fold1_eq_fold eq_commute)
  2393 qed
  2394 
  2395 end
  2396 
  2397 context ab_semigroup_idem_mult
  2398 begin
  2399 
  2400 lemma fun_left_comm_idem: "fun_left_comm_idem(op *)"
  2401 apply unfold_locales
  2402  apply (simp add: mult_ac)
  2403 apply (simp add: mult_idem mult_assoc[symmetric])
  2404 done
  2405 
  2406 
  2407 lemma fold1_insert_idem [simp]:
  2408   assumes nonempty: "A \<noteq> {}" and A: "finite A" 
  2409   shows "fold1 times (insert x A) = x * fold1 times A"
  2410 proof -
  2411   interpret fun_left_comm_idem "op *::'a \<Rightarrow> 'a \<Rightarrow> 'a"
  2412     by (rule fun_left_comm_idem)
  2413   from nonempty obtain a A' where A': "A = insert a A' & a ~: A'"
  2414     by (auto simp add: nonempty_iff)
  2415   show ?thesis
  2416   proof cases
  2417     assume "a = x"
  2418     thus ?thesis
  2419     proof cases
  2420       assume "A' = {}"
  2421       with prems show ?thesis by (simp add: mult_idem)
  2422     next
  2423       assume "A' \<noteq> {}"
  2424       with prems show ?thesis
  2425 	by (simp add: fold1_insert mult_assoc [symmetric] mult_idem)
  2426     qed
  2427   next
  2428     assume "a \<noteq> x"
  2429     with prems show ?thesis
  2430       by (simp add: insert_commute fold1_eq_fold fold_insert_idem)
  2431   qed
  2432 qed
  2433 
  2434 lemma hom_fold1_commute:
  2435 assumes hom: "!!x y. h (x * y) = h x * h y"
  2436 and N: "finite N" "N \<noteq> {}" shows "h (fold1 times N) = fold1 times (h ` N)"
  2437 using N proof (induct rule: finite_ne_induct)
  2438   case singleton thus ?case by simp
  2439 next
  2440   case (insert n N)
  2441   then have "h (fold1 times (insert n N)) = h (n * fold1 times N)" by simp
  2442   also have "\<dots> = h n * h (fold1 times N)" by(rule hom)
  2443   also have "h (fold1 times N) = fold1 times (h ` N)" by(rule insert)
  2444   also have "times (h n) \<dots> = fold1 times (insert (h n) (h ` N))"
  2445     using insert by(simp)
  2446   also have "insert (h n) (h ` N) = h ` insert n N" by simp
  2447   finally show ?case .
  2448 qed
  2449 
  2450 end
  2451 
  2452 
  2453 text{* Now the recursion rules for definitions: *}
  2454 
  2455 lemma fold1_singleton_def: "g = fold1 f \<Longrightarrow> g {a} = a"
  2456 by(simp add:fold1_singleton)
  2457 
  2458 lemma (in ab_semigroup_mult) fold1_insert_def:
  2459   "\<lbrakk> g = fold1 times; finite A; x \<notin> A; A \<noteq> {} \<rbrakk> \<Longrightarrow> g (insert x A) = x * g A"
  2460 by (simp add:fold1_insert)
  2461 
  2462 lemma (in ab_semigroup_idem_mult) fold1_insert_idem_def:
  2463   "\<lbrakk> g = fold1 times; finite A; A \<noteq> {} \<rbrakk> \<Longrightarrow> g (insert x A) = x * g A"
  2464 by simp
  2465 
  2466 subsubsection{* Determinacy for @{term fold1Set} *}
  2467 
  2468 (*Not actually used!!*)
  2469 (*
  2470 context ab_semigroup_mult
  2471 begin
  2472 
  2473 lemma fold_graph_permute:
  2474   "[|fold_graph times id b (insert a A) x; a \<notin> A; b \<notin> A|]
  2475    ==> fold_graph times id a (insert b A) x"
  2476 apply (cases "a=b") 
  2477 apply (auto dest: fold_graph_permute_diff) 
  2478 done
  2479 
  2480 lemma fold1Set_determ:
  2481   "fold1Set times A x ==> fold1Set times A y ==> y = x"
  2482 proof (clarify elim!: fold1Set.cases)
  2483   fix A x B y a b
  2484   assume Ax: "fold_graph times id a A x"
  2485   assume By: "fold_graph times id b B y"
  2486   assume anotA:  "a \<notin> A"
  2487   assume bnotB:  "b \<notin> B"
  2488   assume eq: "insert a A = insert b B"
  2489   show "y=x"
  2490   proof cases
  2491     assume same: "a=b"
  2492     hence "A=B" using anotA bnotB eq by (blast elim!: equalityE)
  2493     thus ?thesis using Ax By same by (blast intro: fold_graph_determ)
  2494   next
  2495     assume diff: "a\<noteq>b"
  2496     let ?D = "B - {a}"
  2497     have B: "B = insert a ?D" and A: "A = insert b ?D"
  2498      and aB: "a \<in> B" and bA: "b \<in> A"
  2499       using eq anotA bnotB diff by (blast elim!:equalityE)+
  2500     with aB bnotB By
  2501     have "fold_graph times id a (insert b ?D) y" 
  2502       by (auto intro: fold_graph_permute simp add: insert_absorb)
  2503     moreover
  2504     have "fold_graph times id a (insert b ?D) x"
  2505       by (simp add: A [symmetric] Ax) 
  2506     ultimately show ?thesis by (blast intro: fold_graph_determ) 
  2507   qed
  2508 qed
  2509 
  2510 lemma fold1Set_equality: "fold1Set times A y ==> fold1 times A = y"
  2511   by (unfold fold1_def) (blast intro: fold1Set_determ)
  2512 
  2513 end
  2514 *)
  2515 
  2516 declare
  2517   empty_fold_graphE [rule del]  fold_graph.intros [rule del]
  2518   empty_fold1SetE [rule del]  insert_fold1SetE [rule del]
  2519   -- {* No more proofs involve these relations. *}
  2520 
  2521 subsubsection {* Lemmas about @{text fold1} *}
  2522 
  2523 context ab_semigroup_mult
  2524 begin
  2525 
  2526 lemma fold1_Un:
  2527 assumes A: "finite A" "A \<noteq> {}"
  2528 shows "finite B \<Longrightarrow> B \<noteq> {} \<Longrightarrow> A Int B = {} \<Longrightarrow>
  2529        fold1 times (A Un B) = fold1 times A * fold1 times B"
  2530 using A by (induct rule: finite_ne_induct)
  2531   (simp_all add: fold1_insert mult_assoc)
  2532 
  2533 lemma fold1_in:
  2534   assumes A: "finite (A)" "A \<noteq> {}" and elem: "\<And>x y. x * y \<in> {x,y}"
  2535   shows "fold1 times A \<in> A"
  2536 using A
  2537 proof (induct rule:finite_ne_induct)
  2538   case singleton thus ?case by simp
  2539 next
  2540   case insert thus ?case using elem by (force simp add:fold1_insert)
  2541 qed
  2542 
  2543 end
  2544 
  2545 lemma (in ab_semigroup_idem_mult) fold1_Un2:
  2546 assumes A: "finite A" "A \<noteq> {}"
  2547 shows "finite B \<Longrightarrow> B \<noteq> {} \<Longrightarrow>
  2548        fold1 times (A Un B) = fold1 times A * fold1 times B"
  2549 using A
  2550 proof(induct rule:finite_ne_induct)
  2551   case singleton thus ?case by simp
  2552 next
  2553   case insert thus ?case by (simp add: mult_assoc)
  2554 qed
  2555 
  2556 
  2557 subsubsection {* Fold1 in lattices with @{const inf} and @{const sup} *}
  2558 
  2559 text{*
  2560   As an application of @{text fold1} we define infimum
  2561   and supremum in (not necessarily complete!) lattices
  2562   over (non-empty) sets by means of @{text fold1}.
  2563 *}
  2564 
  2565 context lower_semilattice
  2566 begin
  2567 
  2568 lemma ab_semigroup_idem_mult_inf:
  2569   "ab_semigroup_idem_mult inf"
  2570   proof qed (rule inf_assoc inf_commute inf_idem)+
  2571 
  2572 lemma below_fold1_iff:
  2573   assumes "finite A" "A \<noteq> {}"
  2574   shows "x \<le> fold1 inf A \<longleftrightarrow> (\<forall>a\<in>A. x \<le> a)"
  2575 proof -
  2576   interpret ab_semigroup_idem_mult inf
  2577     by (rule ab_semigroup_idem_mult_inf)
  2578   show ?thesis using assms by (induct rule: finite_ne_induct) simp_all
  2579 qed
  2580 
  2581 lemma fold1_belowI:
  2582   assumes "finite A"
  2583     and "a \<in> A"
  2584   shows "fold1 inf A \<le> a"
  2585 proof -
  2586   from assms have "A \<noteq> {}" by auto
  2587   from `finite A` `A \<noteq> {}` `a \<in> A` show ?thesis
  2588   proof (induct rule: finite_ne_induct)
  2589     case singleton thus ?case by simp
  2590   next
  2591     interpret ab_semigroup_idem_mult inf
  2592       by (rule ab_semigroup_idem_mult_inf)
  2593     case (insert x F)
  2594     from insert(5) have "a = x \<or> a \<in> F" by simp
  2595     thus ?case
  2596     proof
  2597       assume "a = x" thus ?thesis using insert
  2598         by (simp add: mult_ac)
  2599     next
  2600       assume "a \<in> F"
  2601       hence bel: "fold1 inf F \<le> a" by (rule insert)
  2602       have "inf (fold1 inf (insert x F)) a = inf x (inf (fold1 inf F) a)"
  2603         using insert by (simp add: mult_ac)
  2604       also have "inf (fold1 inf F) a = fold1 inf F"
  2605         using bel by (auto intro: antisym)
  2606       also have "inf x \<dots> = fold1 inf (insert x F)"
  2607         using insert by (simp add: mult_ac)
  2608       finally have aux: "inf (fold1 inf (insert x F)) a = fold1 inf (insert x F)" .
  2609       moreover have "inf (fold1 inf (insert x F)) a \<le> a" by simp
  2610       ultimately show ?thesis by simp
  2611     qed
  2612   qed
  2613 qed
  2614 
  2615 end
  2616 
  2617 lemma (in upper_semilattice) ab_semigroup_idem_mult_sup:
  2618   "ab_semigroup_idem_mult sup"
  2619   by (rule lower_semilattice.ab_semigroup_idem_mult_inf)
  2620     (rule dual_lattice)
  2621 
  2622 context lattice
  2623 begin
  2624 
  2625 definition
  2626   Inf_fin :: "'a set \<Rightarrow> 'a" ("\<Sqinter>\<^bsub>fin\<^esub>_" [900] 900)
  2627 where
  2628   "Inf_fin = fold1 inf"
  2629 
  2630 definition
  2631   Sup_fin :: "'a set \<Rightarrow> 'a" ("\<Squnion>\<^bsub>fin\<^esub>_" [900] 900)
  2632 where
  2633   "Sup_fin = fold1 sup"
  2634 
  2635 lemma Inf_le_Sup [simp]: "\<lbrakk> finite A; A \<noteq> {} \<rbrakk> \<Longrightarrow> \<Sqinter>\<^bsub>fin\<^esub>A \<le> \<Squnion>\<^bsub>fin\<^esub>A"
  2636 apply(unfold Sup_fin_def Inf_fin_def)
  2637 apply(subgoal_tac "EX a. a:A")
  2638 prefer 2 apply blast
  2639 apply(erule exE)
  2640 apply(rule order_trans)
  2641 apply(erule (1) fold1_belowI)
  2642 apply(erule (1) lower_semilattice.fold1_belowI [OF dual_lattice])
  2643 done
  2644 
  2645 lemma sup_Inf_absorb [simp]:
  2646   "finite A \<Longrightarrow> a \<in> A \<Longrightarrow> sup a (\<Sqinter>\<^bsub>fin\<^esub>A) = a"
  2647 apply(subst sup_commute)
  2648 apply(simp add: Inf_fin_def sup_absorb2 fold1_belowI)
  2649 done
  2650 
  2651 lemma inf_Sup_absorb [simp]:
  2652   "finite A \<Longrightarrow> a \<in> A \<Longrightarrow> inf a (\<Squnion>\<^bsub>fin\<^esub>A) = a"
  2653 by (simp add: Sup_fin_def inf_absorb1
  2654   lower_semilattice.fold1_belowI [OF dual_lattice])
  2655 
  2656 end
  2657 
  2658 context distrib_lattice
  2659 begin
  2660 
  2661 lemma sup_Inf1_distrib:
  2662   assumes "finite A"
  2663     and "A \<noteq> {}"
  2664   shows "sup x (\<Sqinter>\<^bsub>fin\<^esub>A) = \<Sqinter>\<^bsub>fin\<^esub>{sup x a|a. a \<in> A}"
  2665 proof -
  2666   interpret ab_semigroup_idem_mult inf
  2667     by (rule ab_semigroup_idem_mult_inf)
  2668   from assms show ?thesis
  2669     by (simp add: Inf_fin_def image_def
  2670       hom_fold1_commute [where h="sup x", OF sup_inf_distrib1])
  2671         (rule arg_cong [where f="fold1 inf"], blast)
  2672 qed
  2673 
  2674 lemma sup_Inf2_distrib:
  2675   assumes A: "finite A" "A \<noteq> {}" and B: "finite B" "B \<noteq> {}"
  2676   shows "sup (\<Sqinter>\<^bsub>fin\<^esub>A) (\<Sqinter>\<^bsub>fin\<^esub>B) = \<Sqinter>\<^bsub>fin\<^esub>{sup a b|a b. a \<in> A \<and> b \<in> B}"
  2677 using A proof (induct rule: finite_ne_induct)
  2678   case singleton thus ?case
  2679     by (simp add: sup_Inf1_distrib [OF B] fold1_singleton_def [OF Inf_fin_def])
  2680 next
  2681   interpret ab_semigroup_idem_mult inf
  2682     by (rule ab_semigroup_idem_mult_inf)
  2683   case (insert x A)
  2684   have finB: "finite {sup x b |b. b \<in> B}"
  2685     by(rule finite_surj[where f = "sup x", OF B(1)], auto)
  2686   have finAB: "finite {sup a b |a b. a \<in> A \<and> b \<in> B}"
  2687   proof -
  2688     have "{sup a b |a b. a \<in> A \<and> b \<in> B} = (UN a:A. UN b:B. {sup a b})"
  2689       by blast
  2690     thus ?thesis by(simp add: insert(1) B(1))
  2691   qed
  2692   have ne: "{sup a b |a b. a \<in> A \<and> b \<in> B} \<noteq> {}" using insert B by blast
  2693   have "sup (\<Sqinter>\<^bsub>fin\<^esub>(insert x A)) (\<Sqinter>\<^bsub>fin\<^esub>B) = sup (inf x (\<Sqinter>\<^bsub>fin\<^esub>A)) (\<Sqinter>\<^bsub>fin\<^esub>B)"
  2694     using insert by (simp add: fold1_insert_idem_def [OF Inf_fin_def])
  2695   also have "\<dots> = inf (sup x (\<Sqinter>\<^bsub>fin\<^esub>B)) (sup (\<Sqinter>\<^bsub>fin\<^esub>A) (\<Sqinter>\<^bsub>fin\<^esub>B))" by(rule sup_inf_distrib2)
  2696   also have "\<dots> = inf (\<Sqinter>\<^bsub>fin\<^esub>{sup x b|b. b \<in> B}) (\<Sqinter>\<^bsub>fin\<^esub>{sup a b|a b. a \<in> A \<and> b \<in> B})"
  2697     using insert by(simp add:sup_Inf1_distrib[OF B])
  2698   also have "\<dots> = \<Sqinter>\<^bsub>fin\<^esub>({sup x b |b. b \<in> B} \<union> {sup a b |a b. a \<in> A \<and> b \<in> B})"
  2699     (is "_ = \<Sqinter>\<^bsub>fin\<^esub>?M")
  2700     using B insert
  2701     by (simp add: Inf_fin_def fold1_Un2 [OF finB _ finAB ne])
  2702   also have "?M = {sup a b |a b. a \<in> insert x A \<and> b \<in> B}"
  2703     by blast
  2704   finally show ?case .
  2705 qed
  2706 
  2707 lemma inf_Sup1_distrib:
  2708   assumes "finite A" and "A \<noteq> {}"
  2709   shows "inf x (\<Squnion>\<^bsub>fin\<^esub>A) = \<Squnion>\<^bsub>fin\<^esub>{inf x a|a. a \<in> A}"
  2710 proof -
  2711   interpret ab_semigroup_idem_mult sup
  2712     by (rule ab_semigroup_idem_mult_sup)
  2713   from assms show ?thesis
  2714     by (simp add: Sup_fin_def image_def hom_fold1_commute [where h="inf x", OF inf_sup_distrib1])
  2715       (rule arg_cong [where f="fold1 sup"], blast)
  2716 qed
  2717 
  2718 lemma inf_Sup2_distrib:
  2719   assumes A: "finite A" "A \<noteq> {}" and B: "finite B" "B \<noteq> {}"
  2720   shows "inf (\<Squnion>\<^bsub>fin\<^esub>A) (\<Squnion>\<^bsub>fin\<^esub>B) = \<Squnion>\<^bsub>fin\<^esub>{inf a b|a b. a \<in> A \<and> b \<in> B}"
  2721 using A proof (induct rule: finite_ne_induct)
  2722   case singleton thus ?case
  2723     by(simp add: inf_Sup1_distrib [OF B] fold1_singleton_def [OF Sup_fin_def])
  2724 next
  2725   case (insert x A)
  2726   have finB: "finite {inf x b |b. b \<in> B}"
  2727     by(rule finite_surj[where f = "%b. inf x b", OF B(1)], auto)
  2728   have finAB: "finite {inf a b |a b. a \<in> A \<and> b \<in> B}"
  2729   proof -
  2730     have "{inf a b |a b. a \<in> A \<and> b \<in> B} = (UN a:A. UN b:B. {inf a b})"
  2731       by blast
  2732     thus ?thesis by(simp add: insert(1) B(1))
  2733   qed
  2734   have ne: "{inf a b |a b. a \<in> A \<and> b \<in> B} \<noteq> {}" using insert B by blast
  2735   interpret ab_semigroup_idem_mult sup
  2736     by (rule ab_semigroup_idem_mult_sup)
  2737   have "inf (\<Squnion>\<^bsub>fin\<^esub>(insert x A)) (\<Squnion>\<^bsub>fin\<^esub>B) = inf (sup x (\<Squnion>\<^bsub>fin\<^esub>A)) (\<Squnion>\<^bsub>fin\<^esub>B)"
  2738     using insert by (simp add: fold1_insert_idem_def [OF Sup_fin_def])
  2739   also have "\<dots> = sup (inf x (\<Squnion>\<^bsub>fin\<^esub>B)) (inf (\<Squnion>\<^bsub>fin\<^esub>A) (\<Squnion>\<^bsub>fin\<^esub>B))" by(rule inf_sup_distrib2)
  2740   also have "\<dots> = sup (\<Squnion>\<^bsub>fin\<^esub>{inf x b|b. b \<in> B}) (\<Squnion>\<^bsub>fin\<^esub>{inf a b|a b. a \<in> A \<and> b \<in> B})"
  2741     using insert by(simp add:inf_Sup1_distrib[OF B])
  2742   also have "\<dots> = \<Squnion>\<^bsub>fin\<^esub>({inf x b |b. b \<in> B} \<union> {inf a b |a b. a \<in> A \<and> b \<in> B})"
  2743     (is "_ = \<Squnion>\<^bsub>fin\<^esub>?M")
  2744     using B insert
  2745     by (simp add: Sup_fin_def fold1_Un2 [OF finB _ finAB ne])
  2746   also have "?M = {inf a b |a b. a \<in> insert x A \<and> b \<in> B}"
  2747     by blast
  2748   finally show ?case .
  2749 qed
  2750 
  2751 end
  2752 
  2753 context complete_lattice
  2754 begin
  2755 
  2756 text {*
  2757   Coincidence on finite sets in complete lattices:
  2758 *}
  2759 
  2760 lemma Inf_fin_Inf:
  2761   assumes "finite A" and "A \<noteq> {}"
  2762   shows "\<Sqinter>\<^bsub>fin\<^esub>A = Inf A"
  2763 proof -
  2764     interpret ab_semigroup_idem_mult inf
  2765     by (rule ab_semigroup_idem_mult_inf)
  2766   from assms show ?thesis
  2767   unfolding Inf_fin_def by (induct A set: finite)
  2768     (simp_all add: Inf_insert_simp)
  2769 qed
  2770 
  2771 lemma Sup_fin_Sup:
  2772   assumes "finite A" and "A \<noteq> {}"
  2773   shows "\<Squnion>\<^bsub>fin\<^esub>A = Sup A"
  2774 proof -
  2775   interpret ab_semigroup_idem_mult sup
  2776     by (rule ab_semigroup_idem_mult_sup)
  2777   from assms show ?thesis
  2778   unfolding Sup_fin_def by (induct A set: finite)
  2779     (simp_all add: Sup_insert_simp)
  2780 qed
  2781 
  2782 end
  2783 
  2784 
  2785 subsubsection {* Fold1 in linear orders with @{const min} and @{const max} *}
  2786 
  2787 text{*
  2788   As an application of @{text fold1} we define minimum
  2789   and maximum in (not necessarily complete!) linear orders
  2790   over (non-empty) sets by means of @{text fold1}.
  2791 *}
  2792 
  2793 context linorder
  2794 begin
  2795 
  2796 lemma ab_semigroup_idem_mult_min:
  2797   "ab_semigroup_idem_mult min"
  2798   proof qed (auto simp add: min_def)
  2799 
  2800 lemma ab_semigroup_idem_mult_max:
  2801   "ab_semigroup_idem_mult max"
  2802   proof qed (auto simp add: max_def)
  2803 
  2804 lemma min_lattice:
  2805   "lower_semilattice (op \<le>) (op <) min"
  2806   proof qed (auto simp add: min_def)
  2807 
  2808 lemma max_lattice:
  2809   "lower_semilattice (op \<ge>) (op >) max"
  2810   proof qed (auto simp add: max_def)
  2811 
  2812 lemma dual_max:
  2813   "ord.max (op \<ge>) = min"
  2814   by (auto simp add: ord.max_def_raw min_def_raw expand_fun_eq)
  2815 
  2816 lemma dual_min:
  2817   "ord.min (op \<ge>) = max"
  2818   by (auto simp add: ord.min_def_raw max_def_raw expand_fun_eq)
  2819 
  2820 lemma strict_below_fold1_iff:
  2821   assumes "finite A" and "A \<noteq> {}"
  2822   shows "x < fold1 min A \<longleftrightarrow> (\<forall>a\<in>A. x < a)"
  2823 proof -
  2824   interpret ab_semigroup_idem_mult min
  2825     by (rule ab_semigroup_idem_mult_min)
  2826   from assms show ?thesis
  2827   by (induct rule: finite_ne_induct)
  2828     (simp_all add: fold1_insert)
  2829 qed
  2830 
  2831 lemma fold1_below_iff:
  2832   assumes "finite A" and "A \<noteq> {}"
  2833   shows "fold1 min A \<le> x \<longleftrightarrow> (\<exists>a\<in>A. a \<le> x)"
  2834 proof -
  2835   interpret ab_semigroup_idem_mult min
  2836     by (rule ab_semigroup_idem_mult_min)
  2837   from assms show ?thesis
  2838   by (induct rule: finite_ne_induct)
  2839     (simp_all add: fold1_insert min_le_iff_disj)
  2840 qed
  2841 
  2842 lemma fold1_strict_below_iff:
  2843   assumes "finite A" and "A \<noteq> {}"
  2844   shows "fold1 min A < x \<longleftrightarrow> (\<exists>a\<in>A. a < x)"
  2845 proof -
  2846   interpret ab_semigroup_idem_mult min
  2847     by (rule ab_semigroup_idem_mult_min)
  2848   from assms show ?thesis
  2849   by (induct rule: finite_ne_induct)
  2850     (simp_all add: fold1_insert min_less_iff_disj)
  2851 qed
  2852 
  2853 lemma fold1_antimono:
  2854   assumes "A \<noteq> {}" and "A \<subseteq> B" and "finite B"
  2855   shows "fold1 min B \<le> fold1 min A"
  2856 proof cases
  2857   assume "A = B" thus ?thesis by simp
  2858 next
  2859   interpret ab_semigroup_idem_mult min
  2860     by (rule ab_semigroup_idem_mult_min)
  2861   assume "A \<noteq> B"
  2862   have B: "B = A \<union> (B-A)" using `A \<subseteq> B` by blast
  2863   have "fold1 min B = fold1 min (A \<union> (B-A))" by(subst B)(rule refl)
  2864   also have "\<dots> = min (fold1 min A) (fold1 min (B-A))"
  2865   proof -
  2866     have "finite A" by(rule finite_subset[OF `A \<subseteq> B` `finite B`])
  2867     moreover have "finite(B-A)" by(rule finite_Diff[OF `finite B`]) (* by(blast intro:finite_Diff prems) fails *)
  2868     moreover have "(B-A) \<noteq> {}" using prems by blast
  2869     moreover have "A Int (B-A) = {}" using prems by blast
  2870     ultimately show ?thesis using `A \<noteq> {}` by (rule_tac fold1_Un)
  2871   qed
  2872   also have "\<dots> \<le> fold1 min A" by (simp add: min_le_iff_disj)
  2873   finally show ?thesis .
  2874 qed
  2875 
  2876 definition
  2877   Min :: "'a set \<Rightarrow> 'a"
  2878 where
  2879   "Min = fold1 min"
  2880 
  2881 definition
  2882   Max :: "'a set \<Rightarrow> 'a"
  2883 where
  2884   "Max = fold1 max"
  2885 
  2886 lemmas Min_singleton [simp] = fold1_singleton_def [OF Min_def]
  2887 lemmas Max_singleton [simp] = fold1_singleton_def [OF Max_def]
  2888 
  2889 lemma Min_insert [simp]:
  2890   assumes "finite A" and "A \<noteq> {}"
  2891   shows "Min (insert x A) = min x (Min A)"
  2892 proof -
  2893   interpret ab_semigroup_idem_mult min
  2894     by (rule ab_semigroup_idem_mult_min)
  2895   from assms show ?thesis by (rule fold1_insert_idem_def [OF Min_def])
  2896 qed
  2897 
  2898 lemma Max_insert [simp]:
  2899   assumes "finite A" and "A \<noteq> {}"
  2900   shows "Max (insert x A) = max x (Max A)"
  2901 proof -
  2902   interpret ab_semigroup_idem_mult max
  2903     by (rule ab_semigroup_idem_mult_max)
  2904   from assms show ?thesis by (rule fold1_insert_idem_def [OF Max_def])
  2905 qed
  2906 
  2907 lemma Min_in [simp]:
  2908   assumes "finite A" and "A \<noteq> {}"
  2909   shows "Min A \<in> A"
  2910 proof -
  2911   interpret ab_semigroup_idem_mult min
  2912     by (rule ab_semigroup_idem_mult_min)
  2913   from assms fold1_in show ?thesis by (fastsimp simp: Min_def min_def)
  2914 qed
  2915 
  2916 lemma Max_in [simp]:
  2917   assumes "finite A" and "A \<noteq> {}"
  2918   shows "Max A \<in> A"
  2919 proof -
  2920   interpret ab_semigroup_idem_mult max
  2921     by (rule ab_semigroup_idem_mult_max)
  2922   from assms fold1_in [of A] show ?thesis by (fastsimp simp: Max_def max_def)
  2923 qed
  2924 
  2925 lemma Min_Un:
  2926   assumes "finite A" and "A \<noteq> {}" and "finite B" and "B \<noteq> {}"
  2927   shows "Min (A \<union> B) = min (Min A) (Min B)"
  2928 proof -
  2929   interpret ab_semigroup_idem_mult min
  2930     by (rule ab_semigroup_idem_mult_min)
  2931   from assms show ?thesis
  2932     by (simp add: Min_def fold1_Un2)
  2933 qed
  2934 
  2935 lemma Max_Un:
  2936   assumes "finite A" and "A \<noteq> {}" and "finite B" and "B \<noteq> {}"
  2937   shows "Max (A \<union> B) = max (Max A) (Max B)"
  2938 proof -
  2939   interpret ab_semigroup_idem_mult max
  2940     by (rule ab_semigroup_idem_mult_max)
  2941   from assms show ?thesis
  2942     by (simp add: Max_def fold1_Un2)
  2943 qed
  2944 
  2945 lemma hom_Min_commute:
  2946   assumes "\<And>x y. h (min x y) = min (h x) (h y)"
  2947     and "finite N" and "N \<noteq> {}"
  2948   shows "h (Min N) = Min (h ` N)"
  2949 proof -
  2950   interpret ab_semigroup_idem_mult min
  2951     by (rule ab_semigroup_idem_mult_min)
  2952   from assms show ?thesis
  2953     by (simp add: Min_def hom_fold1_commute)
  2954 qed
  2955 
  2956 lemma hom_Max_commute:
  2957   assumes "\<And>x y. h (max x y) = max (h x) (h y)"
  2958     and "finite N" and "N \<noteq> {}"
  2959   shows "h (Max N) = Max (h ` N)"
  2960 proof -
  2961   interpret ab_semigroup_idem_mult max
  2962     by (rule ab_semigroup_idem_mult_max)
  2963   from assms show ?thesis
  2964     by (simp add: Max_def hom_fold1_commute [of h])
  2965 qed
  2966 
  2967 lemma Min_le [simp]:
  2968   assumes "finite A" and "x \<in> A"
  2969   shows "Min A \<le> x"
  2970 proof -
  2971   interpret lower_semilattice "op \<le>" "op <" min
  2972     by (rule min_lattice)
  2973   from assms show ?thesis by (simp add: Min_def fold1_belowI)
  2974 qed
  2975 
  2976 lemma Max_ge [simp]:
  2977   assumes "finite A" and "x \<in> A"
  2978   shows "x \<le> Max A"
  2979 proof -
  2980   interpret lower_semilattice "op \<ge>" "op >" max
  2981     by (rule max_lattice)
  2982   from assms show ?thesis by (simp add: Max_def fold1_belowI)
  2983 qed
  2984 
  2985 lemma Min_ge_iff [simp, noatp]:
  2986   assumes "finite A" and "A \<noteq> {}"
  2987   shows "x \<le> Min A \<longleftrightarrow> (\<forall>a\<in>A. x \<le> a)"
  2988 proof -
  2989   interpret lower_semilattice "op \<le>" "op <" min
  2990     by (rule min_lattice)
  2991   from assms show ?thesis by (simp add: Min_def below_fold1_iff)
  2992 qed
  2993 
  2994 lemma Max_le_iff [simp, noatp]:
  2995   assumes "finite A" and "A \<noteq> {}"
  2996   shows "Max A \<le> x \<longleftrightarrow> (\<forall>a\<in>A. a \<le> x)"
  2997 proof -
  2998   interpret lower_semilattice "op \<ge>" "op >" max
  2999     by (rule max_lattice)
  3000   from assms show ?thesis by (simp add: Max_def below_fold1_iff)
  3001 qed
  3002 
  3003 lemma Min_gr_iff [simp, noatp]:
  3004   assumes "finite A" and "A \<noteq> {}"
  3005   shows "x < Min A \<longleftrightarrow> (\<forall>a\<in>A. x < a)"
  3006 proof -
  3007   interpret lower_semilattice "op \<le>" "op <" min
  3008     by (rule min_lattice)
  3009   from assms show ?thesis by (simp add: Min_def strict_below_fold1_iff)
  3010 qed
  3011 
  3012 lemma Max_less_iff [simp, noatp]:
  3013   assumes "finite A" and "A \<noteq> {}"
  3014   shows "Max A < x \<longleftrightarrow> (\<forall>a\<in>A. a < x)"
  3015 proof -
  3016   note Max = Max_def
  3017   interpret linorder "op \<ge>" "op >"
  3018     by (rule dual_linorder)
  3019   from assms show ?thesis
  3020     by (simp add: Max strict_below_fold1_iff [folded dual_max])
  3021 qed
  3022 
  3023 lemma Min_le_iff [noatp]:
  3024   assumes "finite A" and "A \<noteq> {}"
  3025   shows "Min A \<le> x \<longleftrightarrow> (\<exists>a\<in>A. a \<le> x)"
  3026 proof -
  3027   interpret lower_semilattice "op \<le>" "op <" min
  3028     by (rule min_lattice)
  3029   from assms show ?thesis
  3030     by (simp add: Min_def fold1_below_iff)
  3031 qed
  3032 
  3033 lemma Max_ge_iff [noatp]:
  3034   assumes "finite A" and "A \<noteq> {}"
  3035   shows "x \<le> Max A \<longleftrightarrow> (\<exists>a\<in>A. x \<le> a)"
  3036 proof -
  3037   note Max = Max_def
  3038   interpret linorder "op \<ge>" "op >"
  3039     by (rule dual_linorder)
  3040   from assms show ?thesis
  3041     by (simp add: Max fold1_below_iff [folded dual_max])
  3042 qed
  3043 
  3044 lemma Min_less_iff [noatp]:
  3045   assumes "finite A" and "A \<noteq> {}"
  3046   shows "Min A < x \<longleftrightarrow> (\<exists>a\<in>A. a < x)"
  3047 proof -
  3048   interpret lower_semilattice "op \<le>" "op <" min
  3049     by (rule min_lattice)
  3050   from assms show ?thesis
  3051     by (simp add: Min_def fold1_strict_below_iff)
  3052 qed
  3053 
  3054 lemma Max_gr_iff [noatp]:
  3055   assumes "finite A" and "A \<noteq> {}"
  3056   shows "x < Max A \<longleftrightarrow> (\<exists>a\<in>A. x < a)"
  3057 proof -
  3058   note Max = Max_def
  3059   interpret linorder "op \<ge>" "op >"
  3060     by (rule dual_linorder)
  3061   from assms show ?thesis
  3062     by (simp add: Max fold1_strict_below_iff [folded dual_max])
  3063 qed
  3064 
  3065 lemma Min_eqI:
  3066   assumes "finite A"
  3067   assumes "\<And>y. y \<in> A \<Longrightarrow> y \<ge> x"
  3068     and "x \<in> A"
  3069   shows "Min A = x"
  3070 proof (rule antisym)
  3071   from `x \<in> A` have "A \<noteq> {}" by auto
  3072   with assms show "Min A \<ge> x" by simp
  3073 next
  3074   from assms show "x \<ge> Min A" by simp
  3075 qed
  3076 
  3077 lemma Max_eqI:
  3078   assumes "finite A"
  3079   assumes "\<And>y. y \<in> A \<Longrightarrow> y \<le> x"
  3080     and "x \<in> A"
  3081   shows "Max A = x"
  3082 proof (rule antisym)
  3083   from `x \<in> A` have "A \<noteq> {}" by auto
  3084   with assms show "Max A \<le> x" by simp
  3085 next
  3086   from assms show "x \<le> Max A" by simp
  3087 qed
  3088 
  3089 lemma Min_antimono:
  3090   assumes "M \<subseteq> N" and "M \<noteq> {}" and "finite N"
  3091   shows "Min N \<le> Min M"
  3092 proof -
  3093   interpret distrib_lattice "op \<le>" "op <" min max
  3094     by (rule distrib_lattice_min_max)
  3095   from assms show ?thesis by (simp add: Min_def fold1_antimono)
  3096 qed
  3097 
  3098 lemma Max_mono:
  3099   assumes "M \<subseteq> N" and "M \<noteq> {}" and "finite N"
  3100   shows "Max M \<le> Max N"
  3101 proof -
  3102   note Max = Max_def
  3103   interpret linorder "op \<ge>" "op >"
  3104     by (rule dual_linorder)
  3105   from assms show ?thesis
  3106     by (simp add: Max fold1_antimono [folded dual_max])
  3107 qed
  3108 
  3109 lemma finite_linorder_induct[consumes 1, case_names empty insert]:
  3110  "finite A \<Longrightarrow> P {} \<Longrightarrow>
  3111   (!!A b. finite A \<Longrightarrow> ALL a:A. a < b \<Longrightarrow> P A \<Longrightarrow> P(insert b A))
  3112   \<Longrightarrow> P A"
  3113 proof (induct A rule: measure_induct_rule[where f=card])
  3114   fix A :: "'a set"
  3115   assume IH: "!! B. card B < card A \<Longrightarrow> finite B \<Longrightarrow> P {} \<Longrightarrow>
  3116                  (!!A b. finite A \<Longrightarrow> (\<forall>a\<in>A. a<b) \<Longrightarrow> P A \<Longrightarrow> P (insert b A))
  3117                   \<Longrightarrow> P B"
  3118   and "finite A" and "P {}"
  3119   and step: "!!A b. \<lbrakk>finite A; \<forall>a\<in>A. a < b; P A\<rbrakk> \<Longrightarrow> P (insert b A)"
  3120   show "P A"
  3121   proof (cases "A = {}")
  3122     assume "A = {}" thus "P A" using `P {}` by simp
  3123   next
  3124     let ?B = "A - {Max A}" let ?A = "insert (Max A) ?B"
  3125     assume "A \<noteq> {}"
  3126     with `finite A` have "Max A : A" by auto
  3127     hence A: "?A = A" using insert_Diff_single insert_absorb by auto
  3128     note card_Diff1_less[OF `finite A` `Max A : A`]
  3129     moreover have "finite ?B" using `finite A` by simp
  3130     ultimately have "P ?B" using `P {}` step IH by blast
  3131     moreover have "\<forall>a\<in>?B. a < Max A"
  3132       using Max_ge [OF `finite A`] by fastsimp
  3133     ultimately show "P A"
  3134       using A insert_Diff_single step[OF `finite ?B`] by fastsimp
  3135   qed
  3136 qed
  3137 
  3138 end
  3139 
  3140 context ordered_ab_semigroup_add
  3141 begin
  3142 
  3143 lemma add_Min_commute:
  3144   fixes k
  3145   assumes "finite N" and "N \<noteq> {}"
  3146   shows "k + Min N = Min {k + m | m. m \<in> N}"
  3147 proof -
  3148   have "\<And>x y. k + min x y = min (k + x) (k + y)"
  3149     by (simp add: min_def not_le)
  3150       (blast intro: antisym less_imp_le add_left_mono)
  3151   with assms show ?thesis
  3152     using hom_Min_commute [of "plus k" N]
  3153     by simp (blast intro: arg_cong [where f = Min])
  3154 qed
  3155 
  3156 lemma add_Max_commute:
  3157   fixes k
  3158   assumes "finite N" and "N \<noteq> {}"
  3159   shows "k + Max N = Max {k + m | m. m \<in> N}"
  3160 proof -
  3161   have "\<And>x y. k + max x y = max (k + x) (k + y)"
  3162     by (simp add: max_def not_le)
  3163       (blast intro: antisym less_imp_le add_left_mono)
  3164   with assms show ?thesis
  3165     using hom_Max_commute [of "plus k" N]
  3166     by simp (blast intro: arg_cong [where f = Max])
  3167 qed
  3168 
  3169 end
  3170 
  3171 end