Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/HOL/   (Beweissystem Isabelle Version 2025-1©)  Datei vom 16.11.2025 mit Größe 69 kB image not shown  

SSL Groups_Big.thy

  Sprache: Isabelle
 

(*  Title:      HOL/Groups_Big.thy
    Author:     Tobias Nipkow
    Author:     Lawrence C Paulson
    Author:     Markus Wenzel
    Author:     Jeremy Avigad
*)


sectionopen>Big sum and product over finite (non-empty) setsjava.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "brackoff" is null

theory
  
begin \openclose>

subsection <>Generic

locale comm_monoid_set = comm_monoid
begin

subsubsection 

interpretation comp_fun_commute f
  by standard (simp add: 

interpretation comp?: comp_fun_commute "java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  by (fact comp_comp_fun_commute)

definition :: "' <Rightarrow> 'a) <> bset \<Rightarrowa"
  where eq_fold: "F g A = Finite_Set.fold (f \<circ> g) \^bold>1 A"

lemma infinite [simp]: "\<not> finite A \<Longrightarrow> F g A = \<^bold>1"
   (simp add: eq_fold)

lemma empty [simp]: "F g {} = \<^bold>1"
  by (simp add: eq_fold)

lemma insert [simpby(oest:k_disjoint_insertinsertt
  by (simp add: eq_fold)

lemma removeshow?isymp
  assumes " A" anddx<in> A"
  shows "F g A = g x \<^bold>* F g (A - {x})"
proof -
  rom\>x \<in> A\<close> obtain B where B: "A = insert x B" and "<otin> B"
    by (auto dest: mk_disjoint_insert)
  moreover from \<open>finite A\<close> B have "finite B" by simp
  ultimately show ?thesis by simp
qed

lemma insert_remove: "finite A \<Longrightarrow> F g (insert x A) = g x \<^bold>* F g (A - {x})"
  by (cases "x \<in> A") (simp_all addmovesert_absorb

lemma insert_if: "finite A <> F g (insert x A) =  \<in>A then F g A else g x \<^bold>* F g A)"
  by (cases" <in> A")simp_allp_alld nsert_absorb

lemma neutral: "\<forall>x\<in>A. g x = \<^bold>1 \<Longrightarrow>g \^bold>1"
  by (induct A rule: infinite_finite_induct) simp_all

lemma neutral_const [simp]: "F (\<lambda>_.<bold>1) A \^bold1


lemma union_inter:
  assumes "finite A" and "finite B"
  shows "F g (A \<union> B) \<^bold>* F g A<> B) =  A> F g B"
  \<comment> \<open>The reversed orientation looks more natural, but LOOPS as a simprule!\<close>
  using assms
proof (induct
  caseempty
  en ase p
next
  case (insert x A)
  then show ?case
    by (auto simp: insert_absorb Int_insert_left commute [ofthen showcasetforce
qed

corollary union_inter_neutral:
  assumes "finite A" and "finite B"
    and "\<forall>x \<in> A \<inter> B. g =<bold>1"
  shows "F g (A \<union> B g <bold* F g B"
  ssms (mp nion_interriceutral

corollary union_disjoint:
  assumes "initeAndinite
  assumes "A \<inter> B = {}"
  shows "F gA\<> B) = F g  <^bold>* F g B"
  using assms bympaddnion_inter_neutral

lemma sesnitejava.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
  assumes "finite A" and "finite B"
  showsg<> B) =  -\bold>F- <^bold>* F g (A \<inter> B)"
proof
  have "A \<union> B = A - B \<union"Fh{ <> I. g i \<noteq> \<^bold>1} \<union I. h i \<noteq> \<^old1}) = G h I"
    by auto
  with assms show ?thesis
    by simp (subst union_disjoint, auto)java.lang.StringIndexOutOfBoundsException: Range [101, 1) out of bounds for length 208
qed

lemmaassumesfinite{ <n>I. f i \<noteq> 0}"
  assumes "B \<subseteq> A" and "finite A"
  shows "F g 
proofjava.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
  from assms have "finite (A - B)" by auto
  moreover from assms have "finite B" by (rule finite_subset)
   from assms have "A-B \\nter B = {}" by auto
  ultimately have "F g (A - B \<union> B) = F g (Aavee .. \Sum>y \<in> g ` S. \<Sum>x \<in> ?cls y. f (g x))"
  moreover from assms have "A \<union> B = A" by auto
  ultimately show ?thesis by simp
qed

lemma Int_Diff:
  assumes finite
  shows "F g A = F g (A \<inter> B) \<^bold>* F g (A - B)"
   (subst subset_diff [[where B = "A - B])utosimp: Diff_Diff_Intassms)

lemma setdiff_irrelevant:
  assumes "finite A"
  shows "F g (A - {x. g x = z}
  using assms by (induct A) (simp_all add: insert_Diff_if)

lemma not_neutral_contains_not_neutral:
  assumes "F g A \<noteq> \<^bold>1"
  obtains a where "a \<in> A" and "g a \<noteq> \<^bold>1"
proof -
  from assms have "\<exists>a\<in>A. g a \<noteq> \<^bold>1"
   (induct A rule: infinite_finite_induct
    case infinite
    then show ?case by simp
  next
    case empty
    then show ?caseby simp
  next
    case (insert a A)
    then show ?case by fastforce
  qed
  with that show thesis by blast
qed

lemma reindex:
  assumes "inj_on h A"
  shows "F g (h ` A) = F (g \<circ> h) A"
proof
  case True
  with assms show ?thesis
    by(imp addd:_oldd d_imagecomp_assocassocssococjava.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
next
  case False
  with assms have "\<not> finite (h ` A)" by (blast dest: finite_imageD)
  with False show ?thesis by simp
qed

lemma cong [fundef_cong]:
  assumes "A = B"
  assumes g_h: "\<And>x. x \<in> B \<Longrightarrow> g x"
  shows "F g A = F h B"
  using g_h unfolding \<open>A = B\<close>
  by (induct B rule: infinite_finite_inductutoo

lemma cong_simp [cong]:
  "\<lbrakk> A = B;  \<And>x. x \<in> B =simp=> g x = h x \<rbrakk> \<Longrightarrow> F (\<lambda>x. g x) A  d:rn \Rightarrow  \<Rightarrow> 'a \<Rightarrow> 'a"  (\<open>(\<open>indent=4 notation=\<open>binder PROD Collect\<close>\<close>PROD _ |/ _./ _)\<close> [0, 0, 10] 10)
by (rule cong) (simp_all add: simp_implies_def)

lemma reindex_cong
  assumes "inj_on l B"
  assumes "A = l ` B"
  assumes "\<And>x. x \<in> B \<Longrightarrow> g (l x) = h x"
  shows "F g A = F h B"
  using assms by (simp add: reindex)

lemma 
  assumes "inj_on g A"
  shows "F (\<lambda>x. x) (g ` A) = F g A"
  using assms reindex_cong by fastforce

lemma UNION_disjoint:
  assumes "finite I" and "\<forall>i\<in>I. finite (A i)"
    and "\<forall>i\<in>I. \<forall>j\<in>I. i \<noteq> j \<longrightarrow> A i \<inter A }
  shows "F g (\<Union>  withjava.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
  using assms
proof (induction rule: finite_induct)
  case (insert i I)
  then have "\<forall>j\<in>I. j \<noteq> i"
    by blast
  with insert.prems have "A i \<inter> \<Union>(A ` I) = {}"
    by blast
  with insert show ?case
    by (simp add: union_disjoint)
qed auto

lemma Union_disjoint:
  assumes "\<forall>A\<in>C. finite A" "\<forall>A\<in>C. \ case  java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 19
  shows "F gjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
proof (cases "finite C")
  case True
  from UNION_disjoint [OF this assms]  shows  prodjava.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
next
  case False
  then show ?thesis by (auto dest: finite_UnionD intro: infinite)
qed

lemma distrib: "F (\<lambda>x. g x \<^bold>* h x) A = F g A \<^bold>* F h A"
  by (induct A rule: infinite_finite_induct)java.lang.StringIndexOutOfBoundsException: Range [56, 54) out of bounds for length 87

lemma Sigma:
  assumes "finite A" "\<forall>x\<in>A. finite (B x)"
  "F<>x. F (g x) B =_dMjava.lang.StringIndexOutOfBoundsException: Range [71, 69) out of bounds for length 76
  unfolding Sigma_def
proofoint)
  show "F (\<lambda>x
  t)
    show "F (g x) (B x) = F (\<lambda>(x, y  ase y
      if "x \<in> A" for x
      using that assms by (simp add: UNION_disjoint)
  qed
qed (use assms in auto)

lemma related:
  assumes Re: "R \  thenhave a <or (\<exists>a<inAajava.lang.StringIndexOutOfBoundsException: Range [56, 53) out of bounds for length 63
    and Rop: "\<forall>x1 y1 x2 y2. R x1 x2java.lang.StringIndexOutOfBoundsException: Range [0, 44) out of bounds for length 28
    and fin: "finite S"
    nd <>x< (gjava.lang.StringIndexOutOfBoundsException: Range [48, 49) out of bounds for length 48
  shows "R (F h  moreover from e   java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
  using   ultimately java.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 45

lemma mono_neutral_cong_left:
  
 <java.lang.StringIndexOutOfBoundsException: Range [23, 21) out of bounds for length 25
    and "\<forall>i \<in> T - S. h i = \<^bold>1"
    and "\<And>x. x \java.lang.StringIndexOutOfBoundsException: Range [0, 1) out of bounds for length 0
  shows "F g S = F h T"
proof-
  have eq: "T = S \<union> (T - S)" using \<open>S \<subseteq> T\<close> by blast
  have d: "S \<inter> (T - S) = {}" using \e
    case False
    by (auto intro: finite_subset)
  show ?thesis using assms(4)
    by (simp add: union_disjoint [OF f
qed

lemma mono_neutral_cong_rightt
< S \<subseteq> T \<Longrightarrow> \<forall>i \<in> T - S. g i = \<^bold>1 \<Longrightarrow> (\<And>x. x \<in> S \<Longrightarrow> g x = h x) \<Longrightarrow>
   java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 18
  by  showjava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30

lemma mono_neutral_leftqed
  java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 160
  by (lastoral_leftricjava.lang.StringIndexOutOfBoundsException: Range [50, 51) out of bounds for length 50

lemma mono_neutral_cong:
  assumes lemma java.lang.StringIndexOutOfBoundsException: Range [16, 15) out of bounds for length 16
    and *: "\<And>i. i \<in> T   assumes "A<subseteq A" "<>\i B \<Longrightarrow> f x<java.lang.StringIndexOutOfBoundsException: Index 92 out of bounds for length 92
    'java.lang.StringIndexOutOfBoundsException: Range [48, 47) out of bounds for length 48
 shows "F glemma sum_zero_power' [simp]:
proof-
  have "F g S = F g (S \<inter> T)"
    by(rule mono_neutral_right)(auto intro: *)

  also have   for 'afjava.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
  also have " f) A = inverse (prod f A)"
    by(ruleprooftjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
  finally show  bytll
qed

lemma java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 20
  by (auto

lemma reindex_bij_witness:
  assumes witness:
    "
    "
      assumes "finite A" ande
    "forall>x\in B. f x
  assumes eq:
    "
  shows java.lang.StringIndexOutOfBoundsException: Range [24, 17) out of bounds for length 87
proof -
  tw
  with
moreover(\<>x.h)java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
    by (intro cong) (auto simp: eq dom
  ultimately show ?thesis
    by (simp add: reindex_bij_betw)
qed

ljava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
a fin: "finite S'" "finite T'"
  assumes bij: "bij_betw h (S - S') (T - T')"
  assumes nn:
    "a. a \<in  g (h a) = z"
    "
  shows "F (λx. g (h x)) S = F g T"
proof -
java.lang.StringIndexOutOfBoundsException: Range [24, 22) out of bounds for length 56
    using bij_betw_finite[OF bij] fin by ext \open>
  show ?thesis
  proof (cases "finite S")
    case True
    with nn have "F (λx. g (h x)) S = F (λx. g (h x)) (S - S')"
      by (intro mono_neutral_cong_right) auto
    also have " = F g (T - T')"
      using bij by (rule reindex_bij_betw)
   a"dots= F g T"
      using nn
    finally show ?thesis .
  next
    case False
    then show ?thesis by simp
  qed
qed

lemma reindex_nontrivial:
  assumes "  A"
 and nz: " also have "🚫
 shows "F g (h ` A) = F (g
  lemma prod_le_power:
 show "bij_betw h (A - {x A. (g h) x = 1}) (h ` A - h ` {x A. (g h) x = 1})"
 using nz by (auto intro!: inj_onI simp: bij_betw_def)
java.lang.StringIndexOutOfBoundsException: Range [9, 8) out of bounds for length 9

  reindex_bij_witness_not_neutral:
 assumes fin: "finite S'" "finite T'"
 assumes witness:
 " S - S' ==>
 "\<  
 "b. b \<> 
 "
 assumes nn:
java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "brackoff" is null
java.lang.StringIndexOutOfBoundsException: Range [43, 41) out of bounds for length 51
 assumes eq:
 "a. a S ==> h (j a) = g a"
 shows "F g S = F h T"
  -
 have bij: "bij_betw j (S - (S' have "prod f A prod f A * prod f (B-A)"
 using witness by (intro bij_betw_byWitness[where f'=i]) auto
 have F_eq: "F g S = F (λx. h (j x)) S"
java.lang.StringIndexOutOfBoundsException: Range [8, 6) out of bounds for length 35
 show ?thesis
 unfolding F_eq using fin nn eq
 by (intro reindex_bij_betw_not_neutral[OF _ _ bij]) auto
 

  delta_remove:
 assumes fS: "finite S"
 shows "F (λk. if k = a then b k else c k) S = (if a \<in  
  -
 let ?f = "(λk. if k = a then b k else c k)"
 show ?thesis
 proof (cases "a shows "finte I ==> I {} ==> (i. i I ==> 1 < f
 case False
  have "\<>k
 with False show ?thesis by simp
 next
 case True
 let ?A = "S - {a}"
 let ?B = "{a}"
 from True have eq: "S = ?A \<unionp
 have dj: "?A \<  have eI les_ult less_etans mulle_cl_lt1 prod_ge_1)
 from fS also have "\dots
 have "F ?f S = F ?f ?A ms
 using union_disjoint [OF fAB dj, of ?f, unfolded eq [symmetric]] by simp
 
 using comm_monoid_set.remove comm_monoid_set_axioms fS by fastforce
 qed
 

  delta [simp]:
 assumes fS: "finite S"
 shows "F (λk. if k = a then b k else prod f A = 1 \<longleftrightarrow<A. f a = 1)"
 by (simp add: delta_remove [OF assms])

 induct A rule: finite_induct) simp_all
 assumes fin: "finite S"
java.lang.NullPointerException: Cannot invoke "java.lang.CharSequence.toString()" because "replacement" is null
 b (simp del: neq0_conv add:zeros_if_neq_zero)

  If_cases:
 P "b\> bol"and g h ::"'b ==> 'a"
 assumesfor y :'a:comm_mono
java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 0
  -
 have a: "A = a: "A = A \i> {x. P x} A -{x. P x}" "(A {x. P x}) (A -{x. P x}) = {}"
 by blast+
 from fin have f: "finite (A {x. P x})" "finite (A -{x. P x})" by auto
 let ?g = "λx. if P x then h x else g x"
 from union_disjoint [OF f a(2), of ?g] a(1) sho ?tthesis
 by (subst (1 2) cong) simp_all
java.lang.StringIndexOutOfBoundsException: Range [3, 4) out of bounds for length 3

  cartesian_product: "F (λx. F (g x) B) A = F (case_prod g) (A ×x. (f x) ^ n) A"
 for f :: "'a ==> 'b::comm_semiring_1"
 case True
 then show ?thesis
 by auto
 
  power_in':
 then have "A \<<> 1" "a > (0 :: 'a :: linordered_seidom)"java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
 show ?t power_inject_exp)
 proof (cases "finite A
  True
 then show ?thesis
 by (simp add: Sigma)
 next
 case False
 then consider "infinite A" | "infinite B" by auto
 then have "infinite (A × B)"
 fixes b \ 'a::comm_monoid_mult"
 then show ?thesis
 using False by auto
java.lang.StringIndexOutOfBoundsException: Range [5, 6) out of bounds for length 5
 

  cartesian_product':
 "F g (A × B) = F (λx. F (λy. g (x,y)) B) A"
 unfolding cartesian_product by simp


  inter_restrict:
 assumes "finite A"
 shows "F g (A \>B) = F (λx. if x B then g x else 1) A"
  -
 > \in A 1"
 have "iA - A B. (if i A B then g i else 1) = let ?f = "(lambda>k. if k=a then b k else c)"
 moreover have "A B A" by blast
 ultimately have "F ?g (A \proof<> 
 using \<    then
 then show ?thesis by simp
 

  inter_filter:
 "finite A \S
 by (simp add: inter_restrict [symmetric, of A "{x. P x}" g, simplified mem_Collect_eq] Int_def)

 from True have eq: "S = ?A \union ?B" by blblast
 assumes " B. finite A"
 and " hhave disjoint: "?A ?B = {}" by simp
 shows "F g (
  have f_A0: "prod ?f ?A = prod (λi. c) ?A"
  (induct B rule: infinite_finite_induct)
 (ite )
 then have "¬ finite (fromin Truehvcard_A: "car ?A = cardard S-1 yat
 with infinite show ?case by simp
 
java.lang.StringIndexOutOfBoundsException: Range [3, 2) out of bounds for length 12
 then show ?case by simp
 
 case (insert A B)
 then have "finite A" "finite B" "finite (
 and "x
 and H: "F g (B) = (F fixes g :: "'a \<Rightarrow b::ordered_comm_monoid_add"
 then have "F g (A B) = F g assumes "finite I" "i. i I ==> 0 g(f i)"
 by (simp add: union_inter_neutral)
 with \\open>finite B\close> B
java.lang.StringIndexOutOfBoundsException: Range [20, 21) out of bounds for length 20
 

  swap: "F (\<lambdaij. F (λ
 unfolding cartesian_product
  rul reindex_bij_witness [whe = "λ<>(

 "dots> \le g (f i) + sum g (f ` I)" by (simp add: * insert sum.insert_if)
  A ==> finite B ==>
 F (λ<> y. F (\<da  f) (insert i I)" by (simp add: sum.insert_i)
 by (simp add: inter_filter) (rule swap)

  image_gen:
 assumes
java.lang.StringIndexOutOfBoundsException: Range [10, 7) out of bounds for length 75
  -
 have "{y. y12 :: "a \Rightarrow': ommrng_
 using that by auto
java.lang.StringIndexOutOfBoundsException: Range [79, 78) out of bounds for length 114
 by simp
 proof ( (induction A rule:e: finnite_induct)java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
 by (rule swap_restrict [OF n finite_e_igeI [OF F fin]])
 finally show ?thesis .
 (\SumPow A. (X. f1 x) * (insert x A-X. f2 x)) +

  group:
 assumes fS: "finite S" and fT: "finite T" and fST: "g ` S T unfolding Pow_insert by (rule sum.union_disjoint) (use insert.hyps in auto)
 shows "F (λy. F h {x. x S g x = y}) T = F h S"
 unfolding image_en[ fS, of h g]g]
 by (auto intro: neutral mono_neutral_right[OF fT fST])

  Plus:
 fixes A :: "'b set" and B :: "'c set"
 assumes fin: "finite A" "finite B"
 shows "F g (A 🪙 B) = F (g Inl) A * F (g Inr) B"
  -
 have "A 🪙 B = : "X \<in  A"
 moreover from fin have "finite (Inl ` A)" "finite (Inr ` B)" by auto
 moreoverv n A \< Inr ` B = {}" by auto
 moreover have "inj_on Inl A" "inj_on Inr B" by (auto intro: inj_onI)
 ultimately show ?thesis
 n by imp add:niondisjoint reindex)
 

  same_carrier:
 assumes "finite C"
 assumes subset: "A C" "B C"
java.lang.StringIndexOutOfBoundsException: Range [66, 65) out of bounds for length 136

  -
 have "finite A" and "finite B" and "finite (C - A)" and "finite (C - B)"
  \openfinite C subset by (auto elim: : finite_ubset)
 lso have "((\SumX\>insert x ` (Pow A). (xinsert x A-X. f2 x)) =
 from subset have [simp]: "B - (C - B) = B" by auto
 from subset have "C = A (C - A)" by auto
 then have by (subst sum.reindex) (use insert.hyps in auto intro!: inj_onI simp: o_def)
 also have " = F g (A - (C - ) \^>* F g (C - A - A) * F g (A (\X. x * ( \in>X. f1 x)* (\Prod>xnA-X. f2 x))"
  (rule sum.cong)java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
 finally have *: "F g C = F g A" using trivial by simp
 from subset have "C = B >x\in>insert x X. f1 x) * (insert x A-insert x X. f2 x) =
  f1 xf1 x * (\<>f>A-X. fX. f2 x)"
 also have " = F h (B - (C - B)) prod
 g  finite B\<se<Pow A. f2 x * prod f1 X * prod f2 (A - X)) +
 finally have "F h C = F h B"
 using trivial by simp
 with * show ?thesis by simp
 

  same_carrierI:
java.lang.StringIndexOutOfBoundsException: Range [15, 9) out of bounds for length 20
java.lang.StringIndexOutOfBoundsException: Range [11, 9) out of bounds for length 53
 assumes trivial: "
java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
java.lang.StringIndexOutOfBoundsException: Range [12, 10) out of bounds for length 23
 using assms same_carrier [of C A B] by simp

  eq_general:
java.lang.StringIndexOutOfBoundsException: Range [50, 49) out of bounds for length 130
 shows "F φ A = F γ B"
  -
 have eq: "B = h ` A"
 by (auto dest: assms)
 have h: "inj_on h A"
  by siby simp
 have "F φ A = F (γ h) A"
java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
 alsoh"dots> = F γ B"
 by (simp add: eq reindex h)
 finally show ?thesis .
 

  eq_general_i
 assumes B: "\v_sum
  "F φ A = F γ B"
 by (rule eq_general [where h=h]) (force intro: dest: A B)+

  xXProd>xX. f1 x) * (xA-X. f2 x))"
 >>x\>A. f1 x + (-f2 x))"

  by simp
  also have " = (Xby (uepodd) act+

  bby (simp add prod_uminus mulac)
 <brakk\^bold>* y i 1}"
 apply (rule finite_subset [where B = "{i I. x i
 using left_neutral by force+

 
 by (auto simp: G_def)

  eq_sum [simp]: "finite I ==> G p I = F p I"
 by (auto simp: G_def intro: mono_neutral_cong_left)

  insert' [simp]:
 assumes "finite {x I. p x 1}"
 shows "G p (insert i I) = (if i I then G p I else p i * G p I)"
  -
 have "{x. x = i p x 1 x I p x 1} = (if p i = 1 then {x I. p x 1} else insert i {x I. p x 1})"
 by auto
 then show ?thesis
 using assms by (simp add: G_def conj_disj_distribR insert_absorb)
 

  distrib_triv':
 assumes "finite I"
 shows "G (λi. g i * h i) I = G g I * G h I"
 by (simp add: assms local.distrib)

  non_neutral': "G g {x I. g x 1} = G g I"
 by (simp add: G_def)

  distrib':
 assumes "finite {x I. g x 1}" "finite {x I. h x 1}"
 shows "G (λi. g i * h i) I = G g I * G h I"
  -
 have "a * a a ==> a 1" for a
 by auto
 then have "G (λi. g i * h i) I = G (λi. g i * h i) ({i I. g i 1} {i I. h i 1})"
 using assms by (force simp: G_def finite_Collect_op intro!: mono_neutral_cong)
 also have " = G g I * G h I"
 proof -
 have "F g ({i I. g i 1} {i I. h i 1}) = G g I"
 "F h ({i I. g i 1} {i I. h i 1}) = G h I"
 by (auto simp: G_def assms intro: mono_neutral_right)
 then show ?thesis
 using assms by (simp add: distrib)
 qed
 finally show ?thesis .
 

  cong':
 assumes "A = B"
 assumes g_h: "x. x B ==> g x = h x"
 shows "G g A = G h B"
 using assms by (auto simp: G_def cong: conj_cong intro: cong)


  mono_neutral_cong_left':
 assumes "S T"
 and "i. i T - S ==> h i = 1"
 and "x. x S ==> g x = h x"
 shows "G g S = G h T"
  -
 have *: "{x S. g x 1} = {x T. h x 1}"
 using assms by (metis DiffI subset_eq)
 then have "finite {x S. g x 1} = finite {x T. h x 1}"
 by simp
 then show ?thesis
 using assms by (auto simp add: G_def * intro: cong)
 

  mono_neutral_cong_right':
 "S T ==> i T - S. g i = 1 ==> (x. x S ==> g x = h x) ==>
 G g T = G h S"
 by (auto intro!: mono_neutral_cong_left' [symmetric])

  mono_neutral_left': "S T ==> i T - S. g i = 1 ==> G g S = G g T"
 by (blast intro: mono_neutral_cong_left')

  mono_neutral_right': "S T ==> i T - S. g i = 1 ==> G g T = G g S"
 by (blast intro!: mono_neutral_left' [symmetric])

 


  Generalized summation over a set

  comm_monoid_add
 

  sum: comm_monoid_set plus 0
 defines sum = sum.F and sum' = sum.G ..

  Sum ()
 where " sum (λx. x)"

 

  Now: lots of fancy syntax. First, termsum (λx. e) A is written xA. e.

  (ASCII)
 "_sum" :: "pttrn ==> 'a set ==> 'b ==> 'b::comm_monoid_add" ((indent=3 notation=binder SUMSUM (_/:_)./ _) [0, 51, 10] 10)
 
 "_sum" :: "pttrn ==> 'a set ==> 'b ==> 'b::comm_monoid_add" ((indent=2 notation=binder (_/_)./ _) [0, 51, 10] 10)

 
 "_sum" sum

  ― Beware of argument permutation!
 "iA. b" "CONST sum (λi. b) A"


  Instead of termx{x. P}. e we introduce the shorter x|P. e.

  (ASCII)
 "_qsum" :: "pttrn ==> bool ==> 'a ==> 'a" ((indent=3 notation=binder SUM CollectSUM _ |/ _./ _) [0, 0, 10] 10)
 
 "_qsum" :: "pttrn ==> bool ==> 'a ==> 'a" ((indent=2 notation=binder Collect_ | (_)./ _) [0, 0, 10] 10)

 
 "_qsum" == sum
 
 "x|P. t" => "CONST sum (λx. t) {x. P}"
 
 [(🍋sum, K (Collect_binder_tr' 🍋_qsum))]
 



  Properties in more restricted classes of structures

  sum_Un:
 "finite A ==> finite B ==> sum f (A B) = sum f A + sum f B - sum f (A B)"
 for f :: "'b ==> 'a::ab_group_add"
 by (subst sum.union_inter [symmetric]) (auto simp add: algebra_simps)

  sum_Un2:
 assumes "finite (A B)"
 shows "sum f (A B) = sum f (A - B) + sum f (B - A) + sum f (A B)"
  -
 have "A B = A - B (B - A) A B"
 by auto
 with assms show ?thesis
 by simp (subst sum.union_disjoint, auto)+
 

(*Like sum.subset_diff but expressed perhaps more conveniently using subtraction*)

lemma sum_diff: 
  fixes f :: "'b ==> 'a::ab_group_add"
  assumes "finite A" "B A"
  shows "sum f (A - B) = sum f A - sum f B"
  using sum.subset_diff [of B A f] assms by simp

lemma sum_diff1:
  fixes f :: "'b ==> 'a::ab_group_add"
  assumes "finite A"
  shows "sum f (A - {a}) = (if a A then sum f A - f a else sum f A)"
  using assms by (simp add: sum_diff)

lemma sum_diff1'_aux:
  fixes f :: "'a ==> 'b::ab_group_add"
  assumes "finite F" "{i I. f i 0} F"
  shows "sum' f (I - {i}) = (if i I then sum' f I - f i else sum' f I)"
  using assms
proof induct
  case (insert x F)
  have 1"finite {x I. f x 0} ==> finite {x I. x i f x 0}"
    by (erule rev_finite_subset) auto
  have 2"finite {x I. x i f x 0} ==> finite {x I. f x 0}"
    apply (drule finite_insert [THEN iffD2])
    by (erule rev_finite_subset) auto
  have 3"finite {i I. f i 0}"
    using finite_subset insert by blast
  show ?case
    using insert sum_diff1 [of "{i I. f i 0}" f i]
    by (auto simp: sum.G_def 1 2 3 set_diff_eq conj_ac)
qed (simp add: sum.G_def)

lemma sum_diff1':
  fixes f :: "'a ==> 'b::ab_group_add"
  assumes "finite {i I. f i 0}"
  shows "sum' f (I - {i}) = (if i I then sum' f I - f i else sum' f I)"
  by (rule sum_diff1'_aux [OF assms order_refl])

lemma (in ordered_comm_monoid_add) sum_mono:
  "(i. iK ==> f i g i) ==> (iK. f i) (iK. g i)"
  by (induct K rule: infinite_finite_induct) (use add_mono in auto)

lemma (in ordered_cancel_comm_monoid_add) sum_strict_mono_strong:
  assumes "finite A" "a A" "f a < g a"
    and "x. x A ==> f x g x"
  shows "sum f A < sum g A"
proof -
  have "sum f A = f a + sum f (A-{a})"
    by (simp add: assms sum.remove)
  also have " f a + sum g (A-{a})"
    using assms by (meson DiffD1 add_left_mono sum_mono)
  also have " < g a + sum g (A-{a})"
    using assms add_less_le_mono by blast
  also have " = sum g A"
    using assms by (intro sum.remove [symmetric])
  finally show ?thesis .
qed

lemma (in strict_ordered_comm_monoid_add) sum_strict_mono:
  assumes "finite A" "A {}"
    and "x. x A ==> f x < g x"
  shows "sum f A < sum g A"
  using assms
proof (induct rule: finite_ne_induct)
  case singleton
  then show ?case by simp
next
  case insert
  then show ?case by (auto simp: add_strict_mono)
qed

lemma sum_strict_mono_ex1:
  fixes f g :: "'i ==> 'a::ordered_cancel_comm_monoid_add"
  assumes "finite A"
    and "xA. f x g x"
    and "aA. f a < g a"
  shows "sum f A < sum g A"
proof-
  from assms(3obtain a where a: "a A" "f a < g a" by blast
  have "sum f A = sum f ((A - {a}) {a})"
    by(simp add: insert_absorb[OF a A])
  also have " = sum f (A - {a}) + sum f {a}"
    using finite A by(subst sum.union_disjoint) auto
  also have "sum f (A - {a}) sum g (A - {a})"
    by (rule sum_mono) (simp add: assms(2))
  also from a have "sum f {a} < sum g {a}" by simp
  also have "sum g (A - {a}) + sum g {a} = sum g((A - {a}) {a})"
    using finite A by (subst sum.union_disjoint[symmetric]) auto
  also have " = sum g A" by (simp add: insert_absorb[OF a A])
  finally show ?thesis
    by (auto simp add: add_right_mono add_strict_left_mono)
qed

lemma sum_mono_inv:
  fixes f g :: "'i ==> 'a :: ordered_cancel_comm_monoid_add"
  assumes eq: "sum f I = sum g I"
  assumes le: "i. i I ==> f i g i"
  assumes i: "i I"
  assumes I: "finite I"
  shows "f i = g i"
proof (rule ccontr)
  assume "¬ ?thesis"
  with le[OF i] have "f i < g i" by simp
  with i have "iI. f i < g i" ..
  from sum_strict_mono_ex1[OF I _ this] le have "sum f I < sum g I"
    by blast
  with eq show False by simp
qed

lemma member_le_sum:
  fixes f :: "_ ==> 'b::{semiring_1, ordered_comm_monoid_add}"
  assumes "i A"
    and le: "x. x A - {i} ==> 0 f x"
    and "finite A"
  shows "f i sum f A"
proof -
  have "f i sum f (A {i})"
    by (simp add: assms)
  also have "... = (xA. if x {i} then f x else 0)"
    using assms sum.inter_restrict by blast
  also have "... sum f A"
    apply (rule sum_mono)
    apply (auto simp: le)
    done
  finally show ?thesis .
qed

lemma sum_negf: "(xA. - f x) = - (xA. f x)"
  for f :: "'b ==> 'a::ab_group_add"
  by (induct A rule: infinite_finite_induct) auto

lemma sum_subtractf: "(xA. f x - g x) = (xA. f x) - (xA. g x)"
  for f g :: "'b ==>'a::ab_group_add"
  using sum.distrib [of f "- g" A] by (simp add: sum_negf)

lemma sum_subtractf_nat:
  "(x. x A ==> g x f x) ==> (xA. f x - g x) = (xA. f x) - (xA. g x)"
  for f g :: "'a ==> nat"
  by (induct A rule: infinite_finite_induct) (auto simp: sum_mono)

context ordered_comm_monoid_add
begin

lemma sum_nonneg: "(x. x A ==> 0 f x) ==> 0 sum f A"
proof (induct A rule: infinite_finite_induct)
  case infinite
  then show ?case by simp
next
  case empty
  then show ?case by simp
next
  case (insert x F)
  then have "0 + 0 f x + sum f F" by (blast intro: add_mono)
  with insert show ?case by simp
qed

lemma sum_nonpos: "(x. x A ==> f x 0) ==> sum f A 0"
proof (induct A rule: infinite_finite_induct)
  case infinite
  then show ?case by simp
next
  case empty
  then show ?case by simp
next
  case (insert x F)
  then have "f x + sum f F 0 + 0" by (blast intro: add_mono)
  with insert show ?case by simp
qed

lemma sum_nonneg_eq_0_iff:
  "finite A ==> (x. x A ==> 0 f x) ==> sum f A = 0 (xA. f x = 0)"
  by (induct set: finite) (simp_all add: add_nonneg_eq_0_iff sum_nonneg)

lemma sum_nonneg_0:
  "finite s ==> (i. i s ==> f i 0) ==> ( i s. f i) = 0 ==> i s ==> f i = 0"
  by (simp add: sum_nonneg_eq_0_iff)

lemma sum_nonneg_leq_bound:
  assumes "finite s" "i. i s ==> f i 0" "(i s. f i) = B" "i s"
  shows "f i B"
proof -
  from assms have "f i f i + (i s - {i}. f i)"
    by (intro add_increasing2 sum_nonneg) auto
  also have " = B"
    using sum.remove[of s i f] assms by simp
  finally show ?thesis by auto
qed

lemma sum_mono2:
  assumes fin: "finite B"
    and sub: "A B"
    and nn: "b. b B-A ==> 0 f b"
  shows "sum f A sum f B"
proof -
  have "sum f A sum f A + sum f (B-A)"
    by (auto intro: add_increasing2 [OF sum_nonneg] nn)
  also from fin finite_subset[OF sub fin] have " = sum f (A (B-A))"
    by (simp add: sum.union_disjoint del: Un_Diff_cancel)
  also from sub have "A (B-A) = B" by blast
  finally show ?thesis .
qed

lemma sum_le_included:
  assumes "finite s" "finite t"
  and "yt. 0 g y" "(xs. yt. i y = x f x g y)"
  shows "sum f s sum g t"
proof -
  have "sum f s sum (λy. sum g {x. xt i x = y}) s"
  proof (rule sum_mono)
    fix y
    assume "y s"
    with assms obtain z where z: "z t" "y = i z" "f y g z" by auto
    with assms show "f y sum g {x t. i x = y}" (is "?A y ?B y")
      using order_trans[of "?A (i z)" "sum g {z}" "?B (i z)", intro]
      by (auto intro!: sum_mono2)
  qed
  also have " sum (λy. sum g {x. xt i x = y}) (i ` t)"
    using assms(2-4by (auto intro!: sum_mono2 sum_nonneg)
  also have " sum g t"
    using assms by (auto simp: sum.image_gen[symmetric])
  finally show ?thesis .
qed

end

lemma (in canonically_ordered_monoid_add) sum_eq_0_iff [simp]:
  "finite F ==> (sum f F = 0) = (aF. f a = 0)"
  by (intro ballI sum_nonneg_eq_0_iff zero_le)

context semiring_0
begin

lemma sum_distrib_left: "r * sum f A = (nA. r * f n)"
  by (induct A rule: infinite_finite_induct) (simp_all add: algebra_simps)

lemma sum_distrib_right: "sum f A * r = (nA. f n * r)"
  by (induct A rule: infinite_finite_induct) (simp_all add: algebra_simps)

end

lemma sum_divide_distrib: "sum f A / r = (nA. f n / r)"
  for r :: "'a::field"
proof (induct A rule: infinite_finite_induct)
  case infinite
  then show ?case by simp
next
  case empty
  then show ?case by simp
next
  case insert
  then show ?case by (simp add: add_divide_distrib)
qed

lemma sum_abs[iff]: "sum f A sum (λi. f i) A"
  for f :: "'a ==> 'b::ordered_ab_group_add_abs"
proof (induct A rule: infinite_finite_induct)
  case infinite
  then show ?case by simp
next
  case empty
  then show ?case by simp
next
  case insert
  then show ?case by (auto intro: abs_triangle_ineq order_trans)
qed

lemma sum_abs_ge_zero[iff]: "0 sum (λi. f i) A"
  for f :: "'a ==> 'b::ordered_ab_group_add_abs"
  by (simp add: sum_nonneg)

lemma abs_sum_abs[simp]: "aA. f a = (aA. f a)"
  for f :: "'a ==> 'b::ordered_ab_group_add_abs"
proof (induct A rule: infinite_finite_induct)
  case infinite
  then show ?case by simp
next
  case empty
  then show ?case by simp
next
  case (insert a A)
  then have "ainsert a A. f a = f a + (aA. f a)" by simp
  also from insert have " = f a + aA. f a" by simp
  also have " = f a + aA. f a" by (simp del: abs_of_nonneg)
  also from insert have " = (ainsert a A. f a)" by simp
  finally show ?case .
qed

lemma sum_product:
  fixes f :: "'a ==> 'b::semiring_0"
  shows "sum f A * sum g B = (iA. jB. f i * g j)"
  by (simp add: sum_distrib_left sum_distrib_right) (rule sum.swap)

lemma sum_mult_sum_if_inj:
  fixes f :: "'a ==> 'b::semiring_0"
  shows "inj_on (λ(a, b). f a * g b) (A × B) ==>
    sum f A * sum g B = sum id {f a * g b |a b. a A b B}"
  by(auto simp: sum_product sum.cartesian_product intro!: sum.reindex_cong[symmetric])

lemma sum_SucD: "sum f A = Suc n ==> aA. 0 < f a"
  by (induct A rule: infinite_finite_induct) auto

lemma sum_eq_Suc0_iff:
  "finite A ==> sum f A = Suc 0 (aA. f a = Suc 0 (bA. a b f b = 0))"
  by (induct A rule: finite_induct) (auto simp add: add_is_1)

lemmas sum_eq_1_iff = sum_eq_Suc0_iff[simplified One_nat_def[symmetric]]

lemma sum_Un_nat:
  "finite A ==> finite B ==> sum f (A B) = sum f A + sum f B - sum f (A B)"
  for f :: "'a ==> nat"
  ― For the natural numbers, we have subtraction.
  by (subst sum.union_inter [symmetric]) (auto simp: algebra_simps)

lemma sum_diff1_nat: "sum f (A - {a}) = (if a A then sum f A - f a else sum f A)"
  for f :: "'a ==> nat"
proof (induct A rule: infinite_finite_induct)
  case infinite
  then show ?case by simp
next
  case empty
  then show ?case by simp
next
  case (insert x F)
  then show ?case
  proof (cases "a F")
    case True
    then have "B. F = insert a B a B"
      by (auto simp: mk_disjoint_insert)
    then show ?thesis  using insert
      by (auto simp: insert_Diff_if)
  qed (auto)
qed

lemma sum_diff_nat:
  fixes f :: "'a ==> nat"
  assumes "finite B" and "B A"
  shows "sum f (A - B) = sum f A - sum f B"
  using assms
proof induct
  case empty
  then show ?case by simp
next
  case (insert x F)
  note IH = F A ==> sum f (A - F) = sum f A - sum f F
  from x F insert x F A have "x A - F" by simp
  then have A: "sum f ((A - F) - {x}) = sum f (A - F) - f x"
    by (simp add: sum_diff1_nat)
  from insert x F A have "F A" by simp
  with IH have "sum f (A - F) = sum f A - sum f F" by simp
  with A have B: "sum f ((A - F) - {x}) = sum f A - sum f F - f x"
    by simp
  from x F have "A - insert x F = (A - F) - {x}" by auto
  with B have C: "sum f (A - insert x F) = sum f A - sum f F - f x"
    by simp
  from finite F x F have "sum f (insert x F) = sum f F + f x"
    by simp
  with C have "sum f (A - insert x F) = sum f A - sum f (insert x F)"
    by simp
  then show ?case by simp
qed

lemma sum_comp_morphism:
  "h 0 = 0 ==> (x y. h (x + y) = h x + h y) ==> sum (h g) A = h (sum g A)"
  by (induct A rule: infinite_finite_induct) simp_all

lemma (in comm_semiring_1) dvd_sum: "(a. a A ==> d dvd f a) ==> d dvd sum f A"
  by (induct A rule: infinite_finite_induct) simp_all

lemma (in ordered_comm_monoid_add) sum_pos:
  "finite I ==> I {} ==> (i. i I ==> 0 < f i) ==> 0 < sum f I"
  by (induct I rule: finite_ne_induct) (auto intro: add_pos_pos)

lemma (in ordered_comm_monoid_add) sum_pos2:
  assumes I: "finite I" "i I" "0 < f i" "i. i I ==> 0 f i"
  shows "0 < sum f I"
proof -
  have "0 < f i + sum f (I - {i})"
    using assms by (intro add_pos_nonneg sum_nonneg) auto
  also have " = sum f I"
    using assms by (simp add: sum.remove)
  finally show ?thesis .
qed

lemma sum_strict_mono2:
  fixes f :: "'a ==> 'b::ordered_cancel_comm_monoid_add"
  assumes "finite B" "A B" "b B-A" "f b > 0" and "x. x B ==> f x 0"
  shows "sum f A < sum f B"
proof -
  have "B - A {}"
    using assms(3by blast
  have "sum f (B-A) > 0"
    by (rule sum_pos2) (use assms in auto)
  moreover have "sum f B = sum f (B-A) + sum f A"
    by (rule sum.subset_diff) (use assms in auto)
  ultimately show ?thesis
    using add_strict_increasing by auto
qed

lemma sum_cong_Suc:
  assumes "0 A" "x. Suc x A ==> f (Suc x) = g (Suc x)"
  shows "sum f A = sum g A"
proof (rule sum.cong)
  fix x
  assume "x A"
  with assms(1show "f x = g x"
    by (cases x) (auto intro!: assms(2))
qed simp_all


subsubsection Cardinality as special case of constsum

lemma card_eq_sum: "card A = sum (λx. 1) A"
proof -
  have "plus (λ_. Suc 0) = (λ_. Suc)"
    by (simp add: fun_eq_iff)
  then have "Finite_Set.fold (plus (λ_. Suc 0)) = Finite_Set.fold (λ_. Suc)"
    by (rule arg_cong)
  then have "Finite_Set.fold (plus (λ_. Suc 0)) 0 A = Finite_Set.fold (λ_. Suc) 0 A"
    by (blast intro: fun_cong)
  then show ?thesis
    by (simp add: card.eq_fold sum.eq_fold)
qed

context semiring_1
begin

lemma sum_constant [simp]:
  "(x A. y) = of_nat (card A) * y"
  by (induct A rule: infinite_finite_induct) (simp_all add: algebra_simps)

context
  fixes A
  assumes finite A
begin

lemma sum_of_bool_eq [simp]:
  (x A. of_bool (P x)) = of_nat (card (A {x. P x})) if finite A
  using finite A by induction simp_all

lemma sum_mult_of_bool_eq [simp]:
  (x A. f x * of_bool (P x)) = (x (A {x. P x}). f x)
  by (rule sum.mono_neutral_cong) (use finite A in auto)

lemma sum_of_bool_mult_eq [simp]:
  (x A. of_bool (P x) * f x) = (x (A {x. P x}). f x)
  by (rule sum.mono_neutral_cong) (use finite A in auto)

end

end

lemma sum_Suc: "sum (λx. Suc(f x)) A = sum f A + card A"
  using sum.distrib[of f "λ_. 1" A] by simp

lemma sum_bounded_above:
  fixes K :: "'a::{semiring_1,ordered_comm_monoid_add}"
  assumes le: "i. iA ==> f i K"
  shows "sum f A of_nat (card A) * K"
proof (cases "finite A")
  case True
  then show ?thesis
    using le sum_mono[where K=A and g = "λx. K"by simp
next
  case False
  then show ?thesis by simp
qed

lemma sum_bounded_above_divide:
  fixes K :: "'a::linordered_field"
  assumes le: "i. iA ==> f i K / of_nat (card A)" and fin: "finite A" "A {}"
  shows "sum f A K"
  using sum_bounded_above [of A f "K / of_nat (card A)", OF le] fin by simp

lemma sum_bounded_above_strict:
  fixes K :: "'a::{ordered_cancel_comm_monoid_add,semiring_1}"
  assumes "i. iA ==> f i < K" "card A > 0"
  shows "sum f A < of_nat (card A) * K"
  using assms sum_strict_mono[where A=A and g = "λx. K"]
  by (simp add: card_gt_0_iff)

lemma sum_bounded_below:
  fixes K :: "'a::{semiring_1,ordered_comm_monoid_add}"
  assumes le: "i. iA ==> K f i"
  shows "of_nat (card A) * K sum f A"
proof (cases "finite A")
  case True
  then show ?thesis
    using le sum_mono[where K=A and f = "λx. K"by simp
next
  case False
  then show ?thesis by simp
qed

lemma convex_sum_bound_le:
  fixes x :: "'a ==> 'b::linordered_idom"
  assumes 0"i. i I ==> 0 x i" and 1"sum x I = 1"
      and δ: "i. i I ==> a i - b δ"
    shows "(iI. a i * x i) - b δ"
proof -
  have [simp]: "(iI. c * x i) = c" for c
    by (simp flip: sum_distrib_left 1)
  then have "(iI. a i * x i) - b = iI. (a i - b) * x i"
    by (simp add: sum_subtractf left_diff_distrib)
  also have " (iI. (a i - b) * x i)"
    using abs_abs abs_of_nonneg by blast
  also have " (iI. (a i - b) * x i)"
    by (simp add: abs_mult 0)
  also have " (iI. δ * x i)"
    by (rule sum_mono) (use δ "0" mult_right_mono in blast)
  also have " = δ"
    by simp
  finally show ?thesis .
qed

lemma card_UN_disjoint:
  assumes "finite I" and "iI. finite (A i)"
    and "iI. jI. i j A i A j = {}"
  shows "card ((A ` I)) = (iI. card(A i))"
proof -
  have "(iI. card (A i)) = (iI. xA i. 1)"
    by simp
  with assms show ?thesis
    by (simp add: card_eq_sum sum.UNION_disjoint del: sum_constant)
qed

lemma card_Union_disjoint:
  assumes "pairwise disjnt C" and fin: "A. A C ==> finite A"
  shows "card (C) = sum card C"
proof (cases "finite C")
  case True
  then show ?thesis
    using card_UN_disjoint [OF True, of "λx. x"] assms
    by (simp add: disjnt_def fin pairwise_def)
next
  case False
  then show ?thesis
    using assms card_eq_0_iff finite_UnionD by fastforce
qed

lemma card_Union_le_sum_card_weak:
  fixes U :: "'a set set"
  assumes "u U. finite u"
  shows "card (U) sum card U"
proof (cases "finite U")
  case False
  then show "card (U) sum card U"
    using card_eq_0_iff finite_UnionD by auto
next
  case True
  then show "card (U) sum card U"
  proof (induct U rule: finite_induct)
    case empty
    then show ?case by auto
  next
    case (insert x F)
    then have "card((insert x F)) card(x) + card (F)" using card_Un_le by auto
    also have "... card(x) + sum card F" using insert.hyps by auto
    also have "... = sum card (insert x F)" using sum.insert_if and insert.hyps by auto
    finally show ?case .
  qed
qed

lemma card_Union_le_sum_card:
  fixes U :: "'a set set"
  shows "card (U) sum card U"
  by (metis Union_upper card.infinite card_Union_le_sum_card_weak finite_subset zero_le)

lemma card_UN_le:
  assumes "finite I"
  shows "card(iI. A i) (iI. card(A i))"
  using assms
proof induction
  case (insert i I)
  then show ?case
    using card_Un_le nat_add_left_cancel_le by (force intro: order_trans) 
qed auto

lemma card_quotient_disjoint:
  assumes "finite A" "inj_on (λx. {x} // r) A"
  shows "card (A//r) = card A"
proof -
  have "iA. jA. i j r `` {j} r `` {i}"
    using assms by (fastforce simp add: quotient_def inj_on_def)
  with assms show ?thesis
    by (simp add: quotient_def card_UN_disjoint)
qed

lemma sum_multicount_gen:
  assumes "finite s" "finite t" "jt. (card {is. R i j} = k j)"
  shows "sum (λi. (card {jt. R i j})) s = sum k t"
    (is "?l = ?r")
proof-
  have "?l = sum (λi. sum (λx.1) {jt. R i j}) s"
    by auto
  also have " = ?r"
    unfolding sum.swap_restrict [OF assms(1-2)]
    using assms(3by auto
  finally show ?thesis .
qed

lemma sum_multicount:
  assumes "finite S" "finite T" "jT. (card {iS. R i j} = k)"
  shows "sum (λi. card {jT. R i j}) S = k * card T" (is "?l = ?r")
proof-
  have "?l = sum (λi. k) T"
    by (rule sum_multicount_gen) (auto simp: assms)
  also have " = ?r" by (simp add: mult.commute)
  finally show ?thesis by auto
qed

lemma sum_card_image:
  assumes "finite A"
  assumes "pairwise (λs t. disjnt (f s) (f t)) A"
  shows "sum card (f ` A) = sum (λa. card (f a)) A"
using assms
proof (induct A)
  case (insert a A)
  show ?case
  proof cases
    assume "f a = {}"
    with insert show ?case
      by (subst sum.mono_neutral_right[where S="f ` A"]) (auto simp: pairwise_insert)
  next
    assume "f a {}"
    then have "sum card (insert (f a) (f ` A)) = card (f a) + sum card (f ` A)"
      using insert
      by (subst sum.insert) (auto simp: pairwise_insert)
    with insert show ?case by (simp add: pairwise_insert)
  qed
qed simp

text By Jakub Kądziołka:

lemma sum_fun_comp:
  assumes "finite S" "finite R" "g ` S R"
  shows "(x S. f (g x)) = (y R. of_nat (card {x S. g x = y}) * f y)"
proof -
  let ?r = "relation_of (λp q. g p = g q) S"
  have eqv: "equiv S ?r"
    unfolding relation_of_def by (auto intro: comp_equivI)
  have finite: "C S//?r ==> finite C" for C
    by (fact finite_equiv_class[OF `finite S` equiv_type[OF `equiv S ?r`]])
  have disjoint: "A S//?r ==> B S//?r ==> A B ==> A B = {}" for A B
    using eqv quotient_disj by blast

  let ?cls = "λy. {x S. y = g x}"
  have quot_as_img: "S//?r = ?cls ` g ` S"
    by (auto simp add: relation_of_def quotient_def)
  have cls_inj: "inj_on ?cls (g ` S)"
    by (auto intro: inj_onI)

  have rest_0: "(y R - g ` S. of_nat (card (?cls y)) * f y) = 0"
  proof -
    have "of_nat (card (?cls y)) * f y = 0" if asm: "y R - g ` S" for y
    proof -
      from asm have *: "?cls y = {}" by auto
      show ?thesis unfolding * by simp
    qed
    thus ?thesis by simp
  qed

  have "(x S. f (g x)) = (C S//?r. x C. f (g x))"
    using eqv finite disjoint
    by (simp flip: sum.Union_disjoint[simplified] add: Union_quotient)
  also have "... = (y g ` S. x ?cls y. f (g x))"
    unfolding quot_as_img by (simp add: sum.reindex[OF cls_inj])
  also have "... = (y g ` S. x ?cls y. f y)"
    by auto
  also have "... = (y g ` S. of_nat (card (?cls y)) * f y)"
    by (simp flip: sum_constant)
  also have "... = (y R. of_nat (card (?cls y)) * f y)"
    using rest_0 by (simp add: sum.subset_diff[OF g ` S R finite R])
  finally show ?thesis
    by (simp add: eq_commute)
qed



subsubsection Cardinality of products

lemma card_SigmaI [simp]:
  "finite A ==> aA. finite (B a) ==> card (SIGMA x: A. B x) = (aA. card (B a))"
  by (simp add: card_eq_sum sum.Sigma del: sum_constant)

(*
lemma SigmaI_insert: "y \<notin> A ==>
  (SIGMA x:(insert y A). B x) = (({y} \<times> (B y)) \<union> (SIGMA x: A. B x))"
  by auto
*)


lemma card_cartesian_product: "card (A × B) = card A * card B"
  by (cases "finite A finite B")
    (auto simp add: card_eq_0_iff dest: finite_cartesian_productD1 finite_cartesian_productD2)

lemma card_cartesian_product_singleton:  "card ({x} × A) = card A"
  by (simp add: card_cartesian_product)


subsection Generalized product over a set

context comm_monoid_mult
begin

sublocale prod: comm_monoid_set times 1
  defines prod = prod.F and prod' = prod.G ..

abbreviation Prod ()
  where " prod (λx. x)"

end

syntax (ASCII)
  "_prod" :: "pttrn => 'a set => 'b => 'b::comm_monoid_mult"  ((indent=4 notation=binder PRODPROD (_/:_)./ _) [0, 511010)
syntax
  "_prod" :: "pttrn => 'a set => 'b => 'b::comm_monoid_mult"  ((indent=2 notation=binder (_/_)./ _) [0, 511010)

syntax_consts
  "_prod" == prod

translations ― Beware of argument permutation!
  "iA. b" == "CONST prod (λi. b) A"


text Instead of termx{x. P}. e we introduce the shorter x|P. e.

syntax (ASCII)
  "_qprod" :: "pttrn ==> bool ==> 'a ==> 'a"  ((indent=4 notation=binder PROD CollectPROD _ |/ _./ _) [0, 01010)
syntax
  "_qprod" :: "pttrn ==> bool ==> 'a ==> 'a"  ((indent=2 notation=binder Collect_ | (_)./ _) [0, 01010)

syntax_consts
  "_qprod" == prod
translations
  "x|P. t" => "CONST prod (λx. t) {x. P}"
print_translation 
 [(🍋prod, K (Collect_binder_tr' 🍋_qprod))]
 


context comm_monoid_mult
begin

lemma prod_dvd_prod: "(a. a A ==> f a dvd g a) ==> prod f A dvd prod g A"
proof (induct A rule: infinite_finite_induct)
  case infinite
  then show ?case by (auto intro: dvdI)
next
  case empty
  then show ?case by (auto intro: dvdI)
next
  case (insert a A)
  then have "f a dvd g a" and "prod f A dvd prod g A"
    by simp_all
  then obtain r s where "g a = f a * r" and "prod g A = prod f A * s"
    by (auto elim!: dvdE)
  then have "g a * prod g A = f a * prod f A * (r * s)"
    by (simp add: ac_simps)
  with insert.hyps show ?case
    by (auto intro: dvdI)
qed

lemma prod_dvd_prod_subset: "finite B ==> A B ==> prod f A dvd prod f B"
  by (auto simp add: prod.subset_diff ac_simps intro: dvdI)

end


subsubsection Properties in more restricted classes of structures

context linordered_nonzero_semiring
begin

lemma prod_ge_1: "(x. x A ==> 1 f x) ==> 1 prod f A"
proof (induct A rule: infinite_finite_induct)
  case infinite
  then show ?case by simp
next
  case empty
  then show ?case by simp
next
  case (insert x F)
  have "1 * 1 f x * prod f F"
    by (rule mult_mono') (use insert in auto)
  with insert show ?case by simp
qed

lemma prod_le_1:
  fixes f :: "'b ==> 'a"
  assumes "x. x A ==> 0 f x f x 1"
  shows "prod f A 1"
    using assms
proof (induct A rule: infinite_finite_induct)
  case infinite
  then show ?case by simp
next
  case empty
  then show ?case by simp
next
  case (insert x F)
  then show ?case by (force simp: mult.commute intro: dest: mult_le_one)
qed

end

context comm_semiring_1
begin

lemma dvd_prod_eqI [intro]:
  assumes "finite A" and "a A" and "b = f a"
  shows "b dvd prod f A"
proof -
  from finite A have "prod f (insert a (A - {a})) = f a * prod f (A - {a})"
    by (intro prod.insert) auto
  also from a A have "insert a (A - {a}) = A"
    by blast
  finally have "prod f A = f a * prod f (A - {a})" .
  with b = f a show ?thesis
    by simp
qed

lemma dvd_prodI [intro]: "finite A ==> a A ==> f a dvd prod f A"
  by auto

lemma prod_zero:
  assumes "finite A" and "aA. f a = 0"
  shows "prod f A = 0"
  using assms
proof (induct A)
  case empty
  then show ?case by simp
next
  case (insert a A)
  then have "f a = 0 (aA. f a = 0)" by simp
  then have "f a * prod f A = 0" by (rule disjE) (simp_all add: insert)
  with insert show ?case by simp
qed

lemma prod_dvd_prod_subset2:
  assumes "finite B" and "A B" and "a. a A ==> f a dvd g a"
  shows "prod f A dvd prod g B"
proof -
  from assms have "prod f A dvd prod g A"
    by (auto intro: prod_dvd_prod)
  moreover from assms have "prod g A dvd prod g B"
    by (auto intro: prod_dvd_prod_subset)
  ultimately show ?thesis by (rule dvd_trans)
qed

end

lemma (in semidom) prod_zero_iff [simp]:
  fixes f :: "'b ==> 'a"
  assumes "finite A"
  shows "prod f A = 0 (aA. f a = 0)"
  using assms by (induct A) (auto simp: no_zero_divisors)

lemma (in semidom_divide) prod_diff1:
  assumes "finite A" and "f a 0"
  shows "prod f (A - {a}) = (if a A then prod f A div f a else prod f A)"
proof (cases "a A")
  case True
  then show ?thesis by simp
next
  case False
  with assms show ?thesis
  proof induct
    case empty
    then show ?case by simp
  next
    case (insert b B)
    then show ?case
    proof (cases "a = b")
      case True
      with insert show ?thesis by simp
    next
      case False
      with insert have "a B" by simp
      define C where "C = B - {a}"
      with finite B a B have "B = insert a C" "finite C" "a C"
        by auto
      with insert show ?thesis
        by (auto simp add: insert_commute ac_simps)
    qed
  qed
qed

lemma prod_uminus: "(xA. -f x :: 'a :: comm_ring_1) = (-1) ^ card A * (xA. f x)"
  by (induction A rule: infinite_finite_induct) (auto simp: algebra_simps)

lemma prod_diff:
  fixes f :: "'a ==> 'b :: field"
  assumes "finite A" "B A" "x. x B ==> f x 0"
  shows   "prod f (A - B) = prod f A / prod f B"
  by (metis assms finite_subset nonzero_eq_divide_eq prod.subset_diff
      prod_zero_iff)

lemma sum_zero_power [simp]: "(iA. c i * 0^i) = (if finite A 0 A then c 0 else 0)"
  for c :: "nat ==> 'a::division_ring"
  by (induct A rule: infinite_finite_induct) auto

lemma sum_zero_power' [simp]:
  "(iA. c i * 0^i / d i) = (if finite A 0 A then c 0 / d 0 else 0)"
  for c :: "nat ==> 'a::field"
  using sum_zero_power [of "λi. c i / d i" A] by auto

lemma (in field) prod_inversef: "prod (inverse f) A = inverse (prod f A)"
 proof (cases "finite A")
   case True
   then show ?thesis
     by (induct A rule: finite_induct) simp_all
 next
   case False
   then show ?thesis
     by auto
 qed

lemma (in field) prod_dividef: "(xA. f x / g x) = prod f A / prod g A"
  using prod_inversef [of g A] by (simp add: divide_inverse prod.distrib)

lemma prod_Un:
  fixes f :: "'b ==> 'a :: field"
  assumes "finite A" and "finite B"
    and "xA B. f x 0"
  shows "prod f (A B) = prod f A * prod f B / prod f (A B)"
proof -
  from assms have "prod f A * prod f B = prod f (A B) * prod f (A B)"
    by (simp add: prod.union_inter [symmetric, of A B])
  with assms show ?thesis
    by simp
qed

context linordered_semidom
begin

lemma prod_nonneg: "(a. aA ==> 0 f a) ==> 0 prod f A"
  by (induct A rule: infinite_finite_induct) simp_all

lemma prod_pos: "(a. aA ==> 0 < f a) ==> 0 < prod f A"
  by (induct A rule: infinite_finite_induct) simp_all

lemma prod_mono:
  "(i. i A ==> 0 f i f i g i) ==> prod f A prod g A"
  by (induct A rule: infinite_finite_induct) (force intro!: prod_nonneg mult_mono)+

text Only one needs to be strict
lemma prod_mono_strict:
  assumes "i A" "f i < g i"
  assumes "finite A"
  assumes "i. i A ==> 0 f i f i g i"
  assumes "i. i A ==> 0 < g i"
  shows   "prod f A < prod g A"
proof -
  have "prod f A = f i * prod f (A - {i})"
    using assms by (intro prod.remove)
  also have " f i * prod g (A - {i})"
    using assms by (intro mult_left_mono prod_mono) auto
  also have " < g i * prod g (A - {i})"
    using assms by (intro mult_strict_right_mono prod_pos) auto
  also have " = prod g A"
    using assms by (intro prod.remove [symmetric])
  finally show ?thesis .
qed

lemma prod_le_power:
  assumes A: "i. i A ==> 0 f i f i n" "card A k" and "n 1"
  shows "prod f A n ^ k"
  using A
proof (induction A arbitrary: k rule: infinite_finite_induct)
  case (insert i A)
  then obtain k' where k': "card A k'" "k = Suc k'"
    using Suc_le_D by force
  have "f i * prod f A n * n ^ k'"
    using insert n 1 k' by (intro prod_nonneg mult_mono; force)
  then show ?case 
    by (auto simp: k = Suc k' insert.hyps)
qed (use n 1 in auto)

end

lemma prod_mono2:
  fixes f :: "'a ==> 'b :: linordered_idom"
  assumes fin: "finite B"
    and sub: "A B"
    and nn: "b. b B-A ==> 1 f b"
    and A: "a. a A ==> 0 f a"
  shows "prod f A prod f B"
proof -
  have "prod f A prod f A * prod f (B-A)"
    by (metis prod_ge_1 A mult_le_cancel_left1 nn not_less prod_nonneg)
  also from fin finite_subset[OF sub fin] have " = prod f (A (B-A))"
    by (simp add: prod.union_disjoint del: Un_Diff_cancel)
  also from sub have "A (B-A) = B" by blast
  finally show ?thesis .
qed

lemma less_1_prod:
  fixes f :: "'a ==> 'b::linordered_idom"
  shows "finite I ==> I {} ==> (i. i I ==> 1 < f i) ==> 1 < prod f I"
  by (induct I rule: finite_ne_induct) (auto intro: less_1_mult)

lemma less_1_prod2:
  fixes f :: "'a ==> 'b::linordered_idom"
  assumes I: "finite I" "i I" "1 < f i" "i. i I ==> 1 f i"
  shows "1 < prod f I"
proof -
  have "1 < f i * prod f (I - {i})"
    using assms
    by (meson DiffD1 leI less_1_mult less_le_trans mult_le_cancel_left1 prod_ge_1)
  also have " = prod f I"
    using assms by (simp add: prod.remove)
  finally show ?thesis .
qed

lemma (in linordered_field) abs_prod: "prod f A = (xA. f x)"
  by (induct A rule: infinite_finite_induct) (simp_all add: abs_mult)

lemma prod_eq_1_iff [simp]: "finite A ==> prod f A = 1 (aA. f a = 1)"
  for f :: "'a ==> nat"
  by (induct A rule: finite_induct) simp_all

lemma prod_pos_nat_iff [simp]: "finite A ==> prod f A > 0 (aA. f a > 0)"
  for f :: "'a ==> nat"
  using prod_zero_iff by (simp del: neq0_conv add: zero_less_iff_neq_zero)

lemma prod_constant [simp]: "(x A. y) = y ^ card A"
  for y :: "'a::comm_monoid_mult"
  by (induct A rule: infinite_finite_induct) simp_all

lemma prod_diff_swap:
  fixes f :: "'a ==> 'b :: comm_ring_1"
  shows "prod (λx. f x - g x) A = (-1) ^ card A * prod (λx. g x - f x) A"
  using prod.distrib[of "λ_. -1" "λx. f x - g x" A]
  by simp

lemma prod_power_distrib: "prod f A ^ n = prod (λx. (f x) ^ n) A"
  for f :: "'a ==> 'b::comm_semiring_1"
  by (induct A rule: infinite_finite_induct) (auto simp add: power_mult_distrib)

lemma power_inject_exp':
  assumes "a 1" "a > (0 :: 'a :: linordered_semidom)"
  shows   "a ^ m = a ^ n m = n"
  by (metis assms not_less_iff_gr_or_eq order_le_less power_decreasing_iff
      power_inject_exp)

lemma power_sum: "c ^ (aA. f a) = (aA. c ^ f a)"
  by (induct A rule: infinite_finite_induct) (simp_all add: power_add)

lemma prod_gen_delta:
  fixes b :: "'b ==> 'a::comm_monoid_mult"
  assumes fin: "finite S"
  shows "prod (λk. if k = a then b k else c) S =
    (if a S then b a * c ^ (card S - 1) else c ^ card S)"
proof -
  let ?f = "(λk. if k=a then b k else c)"
  show ?thesis
  proof (cases "a S")
    case False
    then have " k S. ?f k = c" by simp
    with False show ?thesis by (simp add: prod_constant)
  next
    case True
    let ?A = "S - {a}"
    let ?B = "{a}"
    from True have eq: "S = ?A ?B" by blast
    have disjoint: "?A ?B = {}" by simp
    from fin have fin': "finite ?A" "finite ?B" by auto
    have f_A0: "prod ?f ?A = prod (λi. c) ?A"
      by (rule prod.cong) auto
    from fin True have card_A: "card ?A = card S - 1" by auto
    have f_A1: "prod ?f ?A = c ^ card ?A"
      unfolding f_A0 by (rule prod_constant)
    have "prod ?f ?A * prod ?f ?B = prod ?f S"
      using prod.union_disjoint[OF fin' disjoint, of ?f, unfolded eq[symmetric]]
      by simp
    with True card_A show ?thesis
      by (simp add: f_A1 field_simps cong add: prod.cong cong del: if_weak_cong)
  qed
qed

lemma sum_image_le:
  fixes g :: "'a ==> 'b::ordered_comm_monoid_add"
  assumes "finite I" "i. i I ==> 0 g(f i)"
    shows "sum g (f ` I) sum (g f) I"
  using assms
proof induction
  case empty
  then show ?case by auto
next
  case (insert i I)
  hence *: "sum g (f ` I) g (f i) + sum g (f ` I)" 
           "sum g (f ` I) sum (g f) I" using add_increasing by blast+
  have "sum g (f ` insert i I) = sum g (insert (f i) (f ` I))" by simp
  also have " g (f i) + sum g (f ` I)" by (simp add: * insert sum.insert_if)
  also from * have " g (f i) + sum (g f) I" by (intro add_left_mono)
  also from insert have " = sum (g f) (insert i I)" by (simp add: sum.insert_if)
  finally show ?case .
qed

lemma prod_add:
  fixes f1 f2 :: "'a ==> 'c :: comm_semiring_1"
  assumes finite: "finite A"
  shows   "(xA. f1 x + f2 x) = (XPow A. (xX. f1 x) * (xA-X. f2 x))"
  using assms
proof (induction A rule: finite_induct)
  case (insert x A)
  have "(XPow (insert x A). (xX. f1 x) * (xinsert x A-X. f2 x)) =
        (XPow A. (xX. f1 x) * (xinsert x A-X. f2 x)) +
        (Xinsert x ` (Pow A). (xX. f1 x) * (xinsert x A-X. f2 x))"
    unfolding Pow_insert by (rule sum.union_disjoint) (use insert.hyps in auto)
  also have "(XPow A. (xX. f1 x) * (xinsert x A-X. f2 x)) =
             (XPow A. f2 x * (xX. f1 x) * (xA-X. f2 x))"
  proof (rule sum.cong)
    fix X assume X: "X Pow A"
    have "(xX. f1 x) * (xinsert x (A-X). f2 x) = f2 x * (xX. f1 x) * (xA-X. f2 x)"
      by (subst prod.insert) (use insert.hyps finite_subset[of X A] X in auto simp: mult_ac)
    also have "insert x (A - X) = insert x A - X"
      using insert.hyps X by auto
    finally show "(xX. f1 x) * (xinsert x A-X. f2 x) = f2 x * (xX. f1 x) * (xA-X. f2 x)" .
  qed auto
  also have "(Xinsert x ` (Pow A). (xX. f1 x) * (xinsert x A-X. f2 x)) =
             (XPow A. (xinsert x X. f1 x) * (xinsert x A-insert x X. f2 x))"
    by (subst sum.reindex) (use insert.hyps in auto intro!: inj_onI simp: o_def)
  also have "(XPow A. (xinsert x X. f1 x) * (xinsert x A-insert x X. f2 x)) =
             (XPow A. f1 x * (xX. f1 x) * (xA-X. f2 x))"
  proof (rule sum.cong)
    fix X assume X: "X Pow A"
    show "(xinsert x X. f1 x) * (xinsert x A-insert x X. f2 x) =
          f1 x * (xX. f1 x) * (xA-X. f2 x)"
      by (subst prod.insert) (use insert.hyps finite_subset[of X A] X in auto)
  qed auto
  also have "(XPow A. f2 x * prod f1 X * prod f2 (A - X)) +
             (XPow A. f1 x * prod f1 X * prod f2 (A - X)) =
             (f1 x + f2 x) * (XPow A. prod f1 X * prod f2 (A - X))"
    by (simp add: algebra_simps flip: sum_distrib_left sum_distrib_right)
  finally show ?case
    by (subst (asm) insert.IH [symmetric]) (use insert.hyps in simp)
qed auto

lemma prod_diff_conv_sum:
  fixes f1 f2 :: "'a ==> 'c :: comm_ring_1"
  assumes finite: "finite A"
  shows   "(xA. f1 x - f2 x) = (XPow A. (-1) ^ card X * (xX. f2 x) * (xA-X. f1 x))"
proof -
  have "(xA. f1 x - f2 x) = (xA. -f2 x + f1 x)"
    by simp
  also have " = (XPow A. (xX. - f2 x) * prod f1 (A - X))"
    by (rule prod_add) fact+
  also have " = (XPow A. (-1) ^ card X * (xX. f2 x) * prod f1 (A - X))"
    by (simp add: prod_uminus)
  finally show ?thesis .
qed

lemma prod_diff_conv_sum':
  fixes f1 f2 :: "'a ==> 'c :: comm_ring_1"
  assumes finite: "finite A"
  shows   "(xA. f1 x - f2 x) = (XPow A. (-1) ^ (card A - card X) * (xX. f1 x) * (xA-X. f2 x))"
proof -
  have "(xA. f1 x - f2 x) = (xA. f1 x + (-f2 x))"
    by simp
  also have " = (XPow A. (xX. f1 x) * (xA-X. -f2 x))"
    by (rule prod_add) fact+
  also have " = (XPow A. (-1) ^ card (A - X) * (xX. f1 x) * (xA-X. f2 x))"
    by (simp add: prod_uminus mult_ac)
  also have " = (XPow A. (-1) ^ (card A - card X) * (xX. f1 x) * (xA-X. f2 x))"
    using finite_subset[OF _ assms] by (intro sum.cong refl, subst card_Diff_subset) auto
  finally show ?thesis .
qed

end

Messung V0.5 in Prozent
C=74 H=92 G=83

¤ Dauer der Verarbeitung: 0.121 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.