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: |