src/HOL/Finite_Set.thy
changeset 14738 83f1a514dcb4
parent 14661 9ead82084de8
child 14740 c8e1937110c2
equal deleted inserted replaced
14737:77ea79aed99d 14738:83f1a514dcb4
   740 
   740 
   741 
   741 
   742 subsection {* Generalized summation over a set *}
   742 subsection {* Generalized summation over a set *}
   743 
   743 
   744 constdefs
   744 constdefs
   745   setsum :: "('a => 'b) => 'a set => 'b::plus_ac0"
   745   setsum :: "('a => 'b) => 'a set => 'b::comm_monoid_add"
   746   "setsum f A == if finite A then fold (op + o f) 0 A else 0"
   746   "setsum f A == if finite A then fold (op + o f) 0 A else 0"
   747 
   747 
   748 syntax
   748 syntax
   749   "_setsum" :: "idt => 'a set => 'b => 'b::plus_ac0"    ("(3\<Sum>_:_. _)" [0, 51, 10] 10)
   749   "_setsum" :: "idt => 'a set => 'b => 'b::comm_monoid_add"    ("(3\<Sum>_:_. _)" [0, 51, 10] 10)
   750 syntax (xsymbols)
   750 syntax (xsymbols)
   751   "_setsum" :: "idt => 'a set => 'b => 'b::plus_ac0"    ("(3\<Sum>_\<in>_. _)" [0, 51, 10] 10)
   751   "_setsum" :: "idt => 'a set => 'b => 'b::comm_monoid_add"    ("(3\<Sum>_\<in>_. _)" [0, 51, 10] 10)
   752 syntax (HTML output)
   752 syntax (HTML output)
   753   "_setsum" :: "idt => 'a set => 'b => 'b::plus_ac0"    ("(3\<Sum>_\<in>_. _)" [0, 51, 10] 10)
   753   "_setsum" :: "idt => 'a set => 'b => 'b::comm_monoid_add"    ("(3\<Sum>_\<in>_. _)" [0, 51, 10] 10)
   754 translations
   754 translations
   755   "\<Sum>i:A. b" == "setsum (%i. b) A"  -- {* Beware of argument permutation! *}
   755   "\<Sum>i:A. b" == "setsum (%i. b) A"  -- {* Beware of argument permutation! *}
   756 
   756 
   757 
   757 
   758 lemma setsum_empty [simp]: "setsum f {} = 0"
   758 lemma setsum_empty [simp]: "setsum f {} = 0"
   759   by (simp add: setsum_def)
   759   by (simp add: setsum_def)
   760 
   760 
   761 lemma setsum_insert [simp]:
   761 lemma setsum_insert [simp]:
   762     "finite F ==> a \<notin> F ==> setsum f (insert a F) = f a + setsum f F"
   762     "finite F ==> a \<notin> F ==> setsum f (insert a F) = f a + setsum f F"
   763   by (simp add: setsum_def
   763   by (simp add: setsum_def
   764     LC.fold_insert [OF LC.intro] plus_ac0_left_commute)
   764     LC.fold_insert [OF LC.intro] add_left_commute)
   765 
   765 
   766 lemma setsum_reindex [rule_format]: "finite B ==>
   766 lemma setsum_reindex [rule_format]: "finite B ==>
   767                   inj_on f B --> setsum h (f ` B) = setsum (h \<circ> f) B"
   767                   inj_on f B --> setsum h (f ` B) = setsum (h \<circ> f) B"
   768 apply (rule finite_induct, assumption, force)
   768 apply (rule finite_induct, assumption, force)
   769 apply (rule impI, auto)
   769 apply (rule impI, auto)
   818 
   818 
   819 lemma setsum_Un_Int: "finite A ==> finite B
   819 lemma setsum_Un_Int: "finite A ==> finite B
   820     ==> setsum g (A Un B) + setsum g (A Int B) = setsum g A + setsum g B"
   820     ==> setsum g (A Un B) + setsum g (A Int B) = setsum g A + setsum g B"
   821   -- {* The reversed orientation looks more natural, but LOOPS as a simprule! *}
   821   -- {* The reversed orientation looks more natural, but LOOPS as a simprule! *}
   822   apply (induct set: Finites, simp)
   822   apply (induct set: Finites, simp)
   823   apply (simp add: plus_ac0 Int_insert_left insert_absorb)
   823   apply (simp add: add_ac Int_insert_left insert_absorb)
   824   done
   824   done
   825 
   825 
   826 lemma setsum_Un_disjoint: "finite A ==> finite B
   826 lemma setsum_Un_disjoint: "finite A ==> finite B
   827   ==> A Int B = {} ==> setsum g (A Un B) = setsum g A + setsum g B"
   827   ==> A Int B = {} ==> setsum g (A Un B) = setsum g A + setsum g B"
   828   apply (subst setsum_Un_Int [symmetric], auto)
   828   apply (subst setsum_Un_Int [symmetric], auto)
   872 
   872 
   873 lemma setsum_addf: "setsum (%x. f x + g x) A = (setsum f A + setsum g A)"
   873 lemma setsum_addf: "setsum (%x. f x + g x) A = (setsum f A + setsum g A)"
   874   apply (case_tac "finite A")
   874   apply (case_tac "finite A")
   875    prefer 2 apply (simp add: setsum_def)
   875    prefer 2 apply (simp add: setsum_def)
   876   apply (erule finite_induct, auto)
   876   apply (erule finite_induct, auto)
   877   apply (simp add: plus_ac0)
   877   apply (simp add: add_ac)
   878   done
   878   done
   879 
   879 
   880 subsubsection {* Properties in more restricted classes of structures *}
   880 subsubsection {* Properties in more restricted classes of structures *}
   881 
   881 
   882 lemma setsum_SucD: "setsum f A = Suc n ==> EX a:A. 0 < f a"
   882 lemma setsum_SucD: "setsum f A = Suc n ==> EX a:A. 0 < f a"
   890     "finite F ==> (setsum f F = 0) = (ALL a:F. f a = (0::nat))"
   890     "finite F ==> (setsum f F = 0) = (ALL a:F. f a = (0::nat))"
   891   by (induct set: Finites) auto
   891   by (induct set: Finites) auto
   892 
   892 
   893 lemma setsum_constant_nat [simp]:
   893 lemma setsum_constant_nat [simp]:
   894     "finite A ==> (\<Sum>x: A. y) = (card A) * y"
   894     "finite A ==> (\<Sum>x: A. y) = (card A) * y"
   895   -- {* Later generalized to any semiring. *}
   895   -- {* Later generalized to any comm_semiring_1_cancel. *}
   896   by (erule finite_induct, auto)
   896   by (erule finite_induct, auto)
   897 
   897 
   898 lemma setsum_Un: "finite A ==> finite B ==>
   898 lemma setsum_Un: "finite A ==> finite B ==>
   899     (setsum f (A Un B) :: nat) = setsum f A + setsum f B - setsum f (A Int B)"
   899     (setsum f (A Un B) :: nat) = setsum f A + setsum f B - setsum f (A Int B)"
   900   -- {* For the natural numbers, we have subtraction. *}
   900   -- {* For the natural numbers, we have subtraction. *}
   901   by (subst setsum_Un_Int [symmetric], auto)
   901   by (subst setsum_Un_Int [symmetric], auto simp add: ring_eq_simps)
   902 
   902 
   903 lemma setsum_Un_ring: "finite A ==> finite B ==>
   903 lemma setsum_Un_ring: "finite A ==> finite B ==>
   904     (setsum f (A Un B) :: 'a :: ring) =
   904     (setsum f (A Un B) :: 'a :: comm_ring_1) =
   905       setsum f A + setsum f B - setsum f (A Int B)"
   905       setsum f A + setsum f B - setsum f (A Int B)"
   906   by (subst setsum_Un_Int [symmetric], auto)
   906   by (subst setsum_Un_Int [symmetric], auto simp add: ring_eq_simps)
   907 
   907 
   908 lemma setsum_diff1: "(setsum f (A - {a}) :: nat) =
   908 lemma setsum_diff1: "(setsum f (A - {a}) :: nat) =
   909     (if a:A then setsum f A - f a else setsum f A)"
   909     (if a:A then setsum f A - f a else setsum f A)"
   910   apply (case_tac "finite A")
   910   apply (case_tac "finite A")
   911    prefer 2 apply (simp add: setsum_def)
   911    prefer 2 apply (simp add: setsum_def)
   912   apply (erule finite_induct)
   912   apply (erule finite_induct)
   913    apply (auto simp add: insert_Diff_if)
   913    apply (auto simp add: insert_Diff_if)
   914   apply (drule_tac a = a in mk_disjoint_insert, auto)
   914   apply (drule_tac a = a in mk_disjoint_insert, auto)
   915   done
   915   done
   916 
   916 
   917 lemma setsum_negf: "finite A ==> setsum (%x. - (f x)::'a::ring) A =
   917 lemma setsum_negf: "finite A ==> setsum (%x. - (f x)::'a::comm_ring_1) A =
   918   - setsum f A"
   918   - setsum f A"
   919   by (induct set: Finites, auto)
   919   by (induct set: Finites, auto)
   920 
   920 
   921 lemma setsum_subtractf: "finite A ==> setsum (%x. ((f x)::'a::ring) - g x) A =
   921 lemma setsum_subtractf: "finite A ==> setsum (%x. ((f x)::'a::comm_ring_1) - g x) A =
   922   setsum f A - setsum g A"
   922   setsum f A - setsum g A"
   923   by (simp add: diff_minus setsum_addf setsum_negf)
   923   by (simp add: diff_minus setsum_addf setsum_negf)
   924 
   924 
   925 lemma setsum_nonneg: "[| finite A;
   925 lemma setsum_nonneg: "[| finite A;
   926     \<forall>x \<in> A. (0::'a::ordered_semiring) \<le> f x |] ==>
   926     \<forall>x \<in> A. (0::'a::ordered_semidom) \<le> f x |] ==>
   927     0 \<le>  setsum f A";
   927     0 \<le>  setsum f A";
   928   apply (induct set: Finites, auto)
   928   apply (induct set: Finites, auto)
   929   apply (subgoal_tac "0 + 0 \<le> f x + setsum f F", simp)
   929   apply (subgoal_tac "0 + 0 \<le> f x + setsum f F", simp)
   930   apply (blast intro: add_mono)
   930   apply (blast intro: add_mono)
   931   done
   931   done
   981 
   981 
   982 
   982 
   983 subsection {* Generalized product over a set *}
   983 subsection {* Generalized product over a set *}
   984 
   984 
   985 constdefs
   985 constdefs
   986   setprod :: "('a => 'b) => 'a set => 'b::times_ac1"
   986   setprod :: "('a => 'b) => 'a set => 'b::comm_monoid_mult"
   987   "setprod f A == if finite A then fold (op * o f) 1 A else 1"
   987   "setprod f A == if finite A then fold (op * o f) 1 A else 1"
   988 
   988 
   989 syntax
   989 syntax
   990   "_setprod" :: "idt => 'a set => 'b => 'b::times_ac1"  ("(3\<Prod>_:_. _)" [0, 51, 10] 10)
   990   "_setprod" :: "idt => 'a set => 'b => 'b::comm_monoid_mult"  ("(3\<Prod>_:_. _)" [0, 51, 10] 10)
   991 
   991 
   992 syntax (xsymbols)
   992 syntax (xsymbols)
   993   "_setprod" :: "idt => 'a set => 'b => 'b::times_ac1"  ("(3\<Prod>_\<in>_. _)" [0, 51, 10] 10)
   993   "_setprod" :: "idt => 'a set => 'b => 'b::comm_monoid_mult"  ("(3\<Prod>_\<in>_. _)" [0, 51, 10] 10)
   994 syntax (HTML output)
   994 syntax (HTML output)
   995   "_setprod" :: "idt => 'a set => 'b => 'b::times_ac1"  ("(3\<Prod>_\<in>_. _)" [0, 51, 10] 10)
   995   "_setprod" :: "idt => 'a set => 'b => 'b::comm_monoid_mult"  ("(3\<Prod>_\<in>_. _)" [0, 51, 10] 10)
   996 translations
   996 translations
   997   "\<Prod>i:A. b" == "setprod (%i. b) A"  -- {* Beware of argument permutation! *}
   997   "\<Prod>i:A. b" == "setprod (%i. b) A"  -- {* Beware of argument permutation! *}
   998 
   998 
   999 lemma setprod_empty [simp]: "setprod f {} = 1"
   999 lemma setprod_empty [simp]: "setprod f {} = 1"
  1000   by (auto simp add: setprod_def)
  1000   by (auto simp add: setprod_def)
  1001 
  1001 
  1002 lemma setprod_insert [simp]: "[| finite A; a \<notin> A |] ==>
  1002 lemma setprod_insert [simp]: "[| finite A; a \<notin> A |] ==>
  1003     setprod f (insert a A) = f a * setprod f A"
  1003     setprod f (insert a A) = f a * setprod f A"
  1004   by (auto simp add: setprod_def LC_def LC.fold_insert
  1004   by (auto simp add: setprod_def LC_def LC.fold_insert
  1005       times_ac1_left_commute)
  1005       mult_left_commute)
  1006 
  1006 
  1007 lemma setprod_reindex [rule_format]: "finite B ==>
  1007 lemma setprod_reindex [rule_format]: "finite B ==>
  1008                   inj_on f B --> setprod h (f ` B) = setprod (h \<circ> f) B"
  1008                   inj_on f B --> setprod h (f ` B) = setprod (h \<circ> f) B"
  1009 apply (rule finite_induct, assumption, force)
  1009 apply (rule finite_induct, assumption, force)
  1010 apply (rule impI, auto)
  1010 apply (rule impI, auto)
  1041   apply (simp add: Ball_def del:insert_Diff_single)
  1041   apply (simp add: Ball_def del:insert_Diff_single)
  1042   done
  1042   done
  1043 
  1043 
  1044 lemma setprod_1: "setprod (%i. 1) A = 1"
  1044 lemma setprod_1: "setprod (%i. 1) A = 1"
  1045   apply (case_tac "finite A")
  1045   apply (case_tac "finite A")
  1046   apply (erule finite_induct, auto simp add: times_ac1)
  1046   apply (erule finite_induct, auto simp add: mult_ac)
  1047   apply (simp add: setprod_def)
  1047   apply (simp add: setprod_def)
  1048   done
  1048   done
  1049 
  1049 
  1050 lemma setprod_1': "ALL a:F. f a = 1 ==> setprod f F = 1"
  1050 lemma setprod_1': "ALL a:F. f a = 1 ==> setprod f F = 1"
  1051   apply (subgoal_tac "setprod f F = setprod (%x. 1) F")
  1051   apply (subgoal_tac "setprod f F = setprod (%x. 1) F")
  1054   done
  1054   done
  1055 
  1055 
  1056 lemma setprod_Un_Int: "finite A ==> finite B
  1056 lemma setprod_Un_Int: "finite A ==> finite B
  1057     ==> setprod g (A Un B) * setprod g (A Int B) = setprod g A * setprod g B"
  1057     ==> setprod g (A Un B) * setprod g (A Int B) = setprod g A * setprod g B"
  1058   apply (induct set: Finites, simp)
  1058   apply (induct set: Finites, simp)
  1059   apply (simp add: times_ac1 insert_absorb)
  1059   apply (simp add: mult_ac insert_absorb)
  1060   apply (simp add: times_ac1 Int_insert_left insert_absorb)
  1060   apply (simp add: mult_ac Int_insert_left insert_absorb)
  1061   done
  1061   done
  1062 
  1062 
  1063 lemma setprod_Un_disjoint: "finite A ==> finite B
  1063 lemma setprod_Un_disjoint: "finite A ==> finite B
  1064   ==> A Int B = {} ==> setprod g (A Un B) = setprod g A * setprod g B"
  1064   ==> A Int B = {} ==> setprod g (A Un B) = setprod g A * setprod g B"
  1065   apply (subst setprod_Un_Int [symmetric], auto simp add: times_ac1)
  1065   apply (subst setprod_Un_Int [symmetric], auto simp add: mult_ac)
  1066   done
  1066   done
  1067 
  1067 
  1068 lemma setprod_UN_disjoint:
  1068 lemma setprod_UN_disjoint:
  1069     "finite I ==> (ALL i:I. finite (A i)) ==>
  1069     "finite I ==> (ALL i:I. finite (A i)) ==>
  1070         (ALL i:I. ALL j:I. i \<noteq> j --> A i Int A j = {}) ==>
  1070         (ALL i:I. ALL j:I. i \<noteq> j --> A i Int A j = {}) ==>
  1108   by (erule setprod_Sigma, auto)
  1108   by (erule setprod_Sigma, auto)
  1109 
  1109 
  1110 lemma setprod_timesf: "setprod (%x. f x * g x) A =
  1110 lemma setprod_timesf: "setprod (%x. f x * g x) A =
  1111     (setprod f A * setprod g A)"
  1111     (setprod f A * setprod g A)"
  1112   apply (case_tac "finite A")
  1112   apply (case_tac "finite A")
  1113    prefer 2 apply (simp add: setprod_def times_ac1)
  1113    prefer 2 apply (simp add: setprod_def mult_ac)
  1114   apply (erule finite_induct, auto)
  1114   apply (erule finite_induct, auto)
  1115   apply (simp add: times_ac1)
  1115   apply (simp add: mult_ac)
  1116   done
  1116   done
  1117 
  1117 
  1118 subsubsection {* Properties in more restricted classes of structures *}
  1118 subsubsection {* Properties in more restricted classes of structures *}
  1119 
  1119 
  1120 lemma setprod_eq_1_iff [simp]:
  1120 lemma setprod_eq_1_iff [simp]:
  1125     y^(card A)"
  1125     y^(card A)"
  1126   apply (erule finite_induct)
  1126   apply (erule finite_induct)
  1127   apply (auto simp add: power_Suc)
  1127   apply (auto simp add: power_Suc)
  1128   done
  1128   done
  1129 
  1129 
  1130 lemma setprod_zero: "finite A ==> EX x: A. f x = (0::'a::semiring) ==>
  1130 lemma setprod_zero: "finite A ==> EX x: A. f x = (0::'a::comm_semiring_1_cancel) ==>
  1131     setprod f A = 0"
  1131     setprod f A = 0"
  1132   apply (induct set: Finites, force, clarsimp)
  1132   apply (induct set: Finites, force, clarsimp)
  1133   apply (erule disjE, auto)
  1133   apply (erule disjE, auto)
  1134   done
  1134   done
  1135 
  1135 
  1136 lemma setprod_nonneg [rule_format]: "(ALL x: A. (0::'a::ordered_ring) \<le> f x)
  1136 lemma setprod_nonneg [rule_format]: "(ALL x: A. (0::'a::ordered_idom) \<le> f x)
  1137      --> 0 \<le> setprod f A"
  1137      --> 0 \<le> setprod f A"
  1138   apply (case_tac "finite A")
  1138   apply (case_tac "finite A")
  1139   apply (induct set: Finites, force, clarsimp)
  1139   apply (induct set: Finites, force, clarsimp)
  1140   apply (subgoal_tac "0 * 0 \<le> f x * setprod f F", force)
  1140   apply (subgoal_tac "0 * 0 \<le> f x * setprod f F", force)
  1141   apply (rule mult_mono, assumption+)
  1141   apply (rule mult_mono, assumption+)
  1142   apply (auto simp add: setprod_def)
  1142   apply (auto simp add: setprod_def)
  1143   done
  1143   done
  1144 
  1144 
  1145 lemma setprod_pos [rule_format]: "(ALL x: A. (0::'a::ordered_ring) < f x)
  1145 lemma setprod_pos [rule_format]: "(ALL x: A. (0::'a::ordered_idom) < f x)
  1146      --> 0 < setprod f A"
  1146      --> 0 < setprod f A"
  1147   apply (case_tac "finite A")
  1147   apply (case_tac "finite A")
  1148   apply (induct set: Finites, force, clarsimp)
  1148   apply (induct set: Finites, force, clarsimp)
  1149   apply (subgoal_tac "0 * 0 < f x * setprod f F", force)
  1149   apply (subgoal_tac "0 * 0 < f x * setprod f F", force)
  1150   apply (rule mult_strict_mono, assumption+)
  1150   apply (rule mult_strict_mono, assumption+)
  1151   apply (auto simp add: setprod_def)
  1151   apply (auto simp add: setprod_def)
  1152   done
  1152   done
  1153 
  1153 
  1154 lemma setprod_nonzero [rule_format]:
  1154 lemma setprod_nonzero [rule_format]:
  1155     "(ALL x y. (x::'a::semiring) * y = 0 --> x = 0 | y = 0) ==>
  1155     "(ALL x y. (x::'a::comm_semiring_1_cancel) * y = 0 --> x = 0 | y = 0) ==>
  1156       finite A ==> (ALL x: A. f x \<noteq> (0::'a)) --> setprod f A \<noteq> 0"
  1156       finite A ==> (ALL x: A. f x \<noteq> (0::'a)) --> setprod f A \<noteq> 0"
  1157   apply (erule finite_induct, auto)
  1157   apply (erule finite_induct, auto)
  1158   done
  1158   done
  1159 
  1159 
  1160 lemma setprod_zero_eq:
  1160 lemma setprod_zero_eq:
  1161     "(ALL x y. (x::'a::semiring) * y = 0 --> x = 0 | y = 0) ==>
  1161     "(ALL x y. (x::'a::comm_semiring_1_cancel) * y = 0 --> x = 0 | y = 0) ==>
  1162      finite A ==> (setprod f A = (0::'a)) = (EX x: A. f x = 0)"
  1162      finite A ==> (setprod f A = (0::'a)) = (EX x: A. f x = 0)"
  1163   apply (insert setprod_zero [of A f] setprod_nonzero [of A f], blast)
  1163   apply (insert setprod_zero [of A f] setprod_nonzero [of A f], blast)
  1164   done
  1164   done
  1165 
  1165 
  1166 lemma setprod_nonzero_field:
  1166 lemma setprod_nonzero_field: