section ‹Big sum and product over function bodies›
theory Groups_Big_Fun
imports
Main
begin
subsection ‹Abstract product›
no_notation times (infixl "*" 70)
no_notation Groups.one ("1")
locale comm_monoid_fun = comm_monoid
begin
definition G :: "('b ⇒ 'a) ⇒ 'a"
where
expand_set: "G g = comm_monoid_set.F f 1 g {a. g a ≠ 1}"
interpretation F: comm_monoid_set f 1
..
lemma expand_superset:
assumes "finite A" and "{a. g a ≠ 1} ⊆ A"
shows "G g = F.F g A"
apply (simp add: expand_set)
apply (rule F.same_carrierI [of A])
apply (simp_all add: assms)
done
lemma conditionalize:
assumes "finite A"
shows "F.F g A = G (λa. if a ∈ A then g a else 1)"
using assms
apply (simp add: expand_set)
apply (rule F.same_carrierI [of A])
apply auto
done
lemma neutral [simp]:
"G (λa. 1) = 1"
by (simp add: expand_set)
lemma update [simp]:
assumes "finite {a. g a ≠ 1}"
assumes "g a = 1"
shows "G (g(a := b)) = b * G g"
proof (cases "b = 1")
case True with ‹g a = 1› show ?thesis
by (simp add: expand_set) (rule F.cong, auto)
next
case False
moreover have "{a'. a' ≠ a ⟶ g a' ≠ 1} = insert a {a. g a ≠ 1}"
by auto
moreover from ‹g a = 1› have "a ∉ {a. g a ≠ 1}"
by simp
moreover have "F.F (λa'. if a' = a then b else g a') {a. g a ≠ 1} = F.F g {a. g a ≠ 1}"
by (rule F.cong) (auto simp add: ‹g a = 1›)
ultimately show ?thesis using ‹finite {a. g a ≠ 1}› by (simp add: expand_set)
qed
lemma infinite [simp]:
"¬ finite {a. g a ≠ 1} ⟹ G g = 1"
by (simp add: expand_set)
lemma cong:
assumes "⋀a. g a = h a"
shows "G g = G h"
using assms by (simp add: expand_set)
lemma strong_cong [cong]:
assumes "⋀a. g a = h a"
shows "G (λa. g a) = G (λa. h a)"
using assms by (fact cong)
lemma not_neutral_obtains_not_neutral:
assumes "G g ≠ 1"
obtains a where "g a ≠ 1"
using assms by (auto elim: F.not_neutral_contains_not_neutral simp add: expand_set)
lemma reindex_cong:
assumes "bij l"
assumes "g ∘ l = h"
shows "G g = G h"
proof -
from assms have unfold: "h = g ∘ l" by simp
from ‹bij l› have "inj l" by (rule bij_is_inj)
then have "inj_on l {a. h a ≠ 1}" by (rule subset_inj_on) simp
moreover from ‹bij l› have "{a. g a ≠ 1} = l ` {a. h a ≠ 1}"
by (auto simp add: image_Collect unfold elim: bij_pointE)
moreover have "⋀x. x ∈ {a. h a ≠ 1} ⟹ g (l x) = h x"
by (simp add: unfold)
ultimately have "F.F g {a. g a ≠ 1} = F.F h {a. h a ≠ 1}"
by (rule F.reindex_cong)
then show ?thesis by (simp add: expand_set)
qed
lemma distrib:
assumes "finite {a. g a ≠ 1}" and "finite {a. h a ≠ 1}"
shows "G (λa. g a * h a) = G g * G h"
proof -
from assms have "finite ({a. g a ≠ 1} ∪ {a. h a ≠ 1})" by simp
moreover have "{a. g a * h a ≠ 1} ⊆ {a. g a ≠ 1} ∪ {a. h a ≠ 1}"
by auto (drule sym, simp)
ultimately show ?thesis
using assms
by (simp add: expand_superset [of "{a. g a ≠ 1} ∪ {a. h a ≠ 1}"] F.distrib)
qed
lemma commute:
assumes "finite C"
assumes subset: "{a. ∃b. g a b ≠ 1} × {b. ∃a. g a b ≠ 1} ⊆ C" (is "?A × ?B ⊆ C")
shows "G (λa. G (g a)) = G (λb. G (λa. g a b))"
proof -
from ‹finite C› subset
have "finite ({a. ∃b. g a b ≠ 1} × {b. ∃a. g a b ≠ 1})"
by (rule rev_finite_subset)
then have fins:
"finite {b. ∃a. g a b ≠ 1}" "finite {a. ∃b. g a b ≠ 1}"
by (auto simp add: finite_cartesian_product_iff)
have subsets: "⋀a. {b. g a b ≠ 1} ⊆ {b. ∃a. g a b ≠ 1}"
"⋀b. {a. g a b ≠ 1} ⊆ {a. ∃b. g a b ≠ 1}"
"{a. F.F (g a) {b. ∃a. g a b ≠ 1} ≠ 1} ⊆ {a. ∃b. g a b ≠ 1}"
"{a. F.F (λaa. g aa a) {a. ∃b. g a b ≠ 1} ≠ 1} ⊆ {b. ∃a. g a b ≠ 1}"
by (auto elim: F.not_neutral_contains_not_neutral)
from F.commute have
"F.F (λa. F.F (g a) {b. ∃a. g a b ≠ 1}) {a. ∃b. g a b ≠ 1} =
F.F (λb. F.F (λa. g a b) {a. ∃b. g a b ≠ 1}) {b. ∃a. g a b ≠ 1}" .
with subsets fins have "G (λa. F.F (g a) {b. ∃a. g a b ≠ 1}) =
G (λb. F.F (λa. g a b) {a. ∃b. g a b ≠ 1})"
by (auto simp add: expand_superset [of "{b. ∃a. g a b ≠ 1}"]
expand_superset [of "{a. ∃b. g a b ≠ 1}"])
with subsets fins show ?thesis
by (auto simp add: expand_superset [of "{b. ∃a. g a b ≠ 1}"]
expand_superset [of "{a. ∃b. g a b ≠ 1}"])
qed
lemma cartesian_product:
assumes "finite C"
assumes subset: "{a. ∃b. g a b ≠ 1} × {b. ∃a. g a b ≠ 1} ⊆ C" (is "?A × ?B ⊆ C")
shows "G (λa. G (g a)) = G (λ(a, b). g a b)"
proof -
from subset ‹finite C› have fin_prod: "finite (?A × ?B)"
by (rule finite_subset)
from fin_prod have "finite ?A" and "finite ?B"
by (auto simp add: finite_cartesian_product_iff)
have *: "G (λa. G (g a)) =
(F.F (λa. F.F (g a) {b. ∃a. g a b ≠ 1}) {a. ∃b. g a b ≠ 1})"
apply (subst expand_superset [of "?B"])
apply (rule ‹finite ?B›)
apply auto
apply (subst expand_superset [of "?A"])
apply (rule ‹finite ?A›)
apply auto
apply (erule F.not_neutral_contains_not_neutral)
apply auto
done
have "{p. (case p of (a, b) ⇒ g a b) ≠ 1} ⊆ ?A × ?B"
by auto
with subset have **: "{p. (case p of (a, b) ⇒ g a b) ≠ 1} ⊆ C"
by blast
show ?thesis
apply (simp add: *)
apply (simp add: F.cartesian_product)
apply (subst expand_superset [of C])
apply (rule ‹finite C›)
apply (simp_all add: **)
apply (rule F.same_carrierI [of C])
apply (rule ‹finite C›)
apply (simp_all add: subset)
apply auto
done
qed
lemma cartesian_product2:
assumes fin: "finite D"
assumes subset: "{(a, b). ∃c. g a b c ≠ 1} × {c. ∃a b. g a b c ≠ 1} ⊆ D" (is "?AB × ?C ⊆ D")
shows "G (λ(a, b). G (g a b)) = G (λ(a, b, c). g a b c)"
proof -
have bij: "bij (λ(a, b, c). ((a, b), c))"
by (auto intro!: bijI injI simp add: image_def)
have "{p. ∃c. g (fst p) (snd p) c ≠ 1} × {c. ∃p. g (fst p) (snd p) c ≠ 1} ⊆ D"
by auto (insert subset, blast)
with fin have "G (λp. G (g (fst p) (snd p))) = G (λ(p, c). g (fst p) (snd p) c)"
by (rule cartesian_product)
then have "G (λ(a, b). G (g a b)) = G (λ((a, b), c). g a b c)"
by (auto simp add: split_def)
also have "G (λ((a, b), c). g a b c) = G (λ(a, b, c). g a b c)"
using bij by (rule reindex_cong [of "λ(a, b, c). ((a, b), c)"]) (simp add: fun_eq_iff)
finally show ?thesis .
qed
lemma delta [simp]:
"G (λb. if b = a then g b else 1) = g a"
proof -
have "{b. (if b = a then g b else 1) ≠ 1} ⊆ {a}" by auto
then show ?thesis by (simp add: expand_superset [of "{a}"])
qed
lemma delta' [simp]:
"G (λb. if a = b then g b else 1) = g a"
proof -
have "(λb. if a = b then g b else 1) = (λb. if b = a then g b else 1)"
by (simp add: fun_eq_iff)
then have "G (λb. if a = b then g b else 1) = G (λb. if b = a then g b else 1)"
by (simp cong del: strong_cong)
then show ?thesis by simp
qed
end
notation times (infixl "*" 70)
notation Groups.one ("1")
subsection ‹Concrete sum›
context comm_monoid_add
begin
sublocale Sum_any: comm_monoid_fun plus 0
defines
Sum_any = Sum_any.G
rewrites
"comm_monoid_set.F plus 0 = setsum"
proof -
show "comm_monoid_fun plus 0" ..
then interpret Sum_any: comm_monoid_fun plus 0 .
from setsum_def show "comm_monoid_set.F plus 0 = setsum" by (auto intro: sym)
qed
end
syntax (ASCII)
"_Sum_any" :: "pttrn ⇒ 'a ⇒ 'a::comm_monoid_add" ("(3SUM _. _)" [0, 10] 10)
syntax
"_Sum_any" :: "pttrn ⇒ 'a ⇒ 'a::comm_monoid_add" ("(3∑_. _)" [0, 10] 10)
translations
"∑a. b" ⇌ "CONST Sum_any (λa. b)"
lemma Sum_any_left_distrib:
fixes r :: "'a :: semiring_0"
assumes "finite {a. g a ≠ 0}"
shows "Sum_any g * r = (∑n. g n * r)"
proof -
note assms
moreover have "{a. g a * r ≠ 0} ⊆ {a. g a ≠ 0}" by auto
ultimately show ?thesis
by (simp add: setsum_left_distrib Sum_any.expand_superset [of "{a. g a ≠ 0}"])
qed
lemma Sum_any_right_distrib:
fixes r :: "'a :: semiring_0"
assumes "finite {a. g a ≠ 0}"
shows "r * Sum_any g = (∑n. r * g n)"
proof -
note assms
moreover have "{a. r * g a ≠ 0} ⊆ {a. g a ≠ 0}" by auto
ultimately show ?thesis
by (simp add: setsum_right_distrib Sum_any.expand_superset [of "{a. g a ≠ 0}"])
qed
lemma Sum_any_product:
fixes f g :: "'b ⇒ 'a::semiring_0"
assumes "finite {a. f a ≠ 0}" and "finite {b. g b ≠ 0}"
shows "Sum_any f * Sum_any g = (∑a. ∑b. f a * g b)"
proof -
have subset_f: "{a. (∑b. f a * g b) ≠ 0} ⊆ {a. f a ≠ 0}"
by rule (simp, rule, auto)
moreover have subset_g: "⋀a. {b. f a * g b ≠ 0} ⊆ {b. g b ≠ 0}"
by rule (simp, rule, auto)
ultimately show ?thesis using assms
by (auto simp add: Sum_any.expand_set [of f] Sum_any.expand_set [of g]
Sum_any.expand_superset [of "{a. f a ≠ 0}"] Sum_any.expand_superset [of "{b. g b ≠ 0}"]
setsum_product)
qed
lemma Sum_any_eq_zero_iff [simp]:
fixes f :: "'a ⇒ nat"
assumes "finite {a. f a ≠ 0}"
shows "Sum_any f = 0 ⟷ f = (λ_. 0)"
using assms by (simp add: Sum_any.expand_set fun_eq_iff)
subsection ‹Concrete product›
context comm_monoid_mult
begin
sublocale Prod_any: comm_monoid_fun times 1
defines
Prod_any = Prod_any.G
rewrites
"comm_monoid_set.F times 1 = setprod"
proof -
show "comm_monoid_fun times 1" ..
then interpret Prod_any: comm_monoid_fun times 1 .
from setprod_def show "comm_monoid_set.F times 1 = setprod" by (auto intro: sym)
qed
end
syntax (ASCII)
"_Prod_any" :: "pttrn ⇒ 'a ⇒ 'a::comm_monoid_mult" ("(3PROD _. _)" [0, 10] 10)
syntax
"_Prod_any" :: "pttrn ⇒ 'a ⇒ 'a::comm_monoid_mult" ("(3∏_. _)" [0, 10] 10)
translations
"∏a. b" == "CONST Prod_any (λa. b)"
lemma Prod_any_zero:
fixes f :: "'b ⇒ 'a :: comm_semiring_1"
assumes "finite {a. f a ≠ 1}"
assumes "f a = 0"
shows "(∏a. f a) = 0"
proof -
from ‹f a = 0› have "f a ≠ 1" by simp
with ‹f a = 0› have "∃a. f a ≠ 1 ∧ f a = 0" by blast
with ‹finite {a. f a ≠ 1}› show ?thesis
by (simp add: Prod_any.expand_set setprod_zero)
qed
lemma Prod_any_not_zero:
fixes f :: "'b ⇒ 'a :: comm_semiring_1"
assumes "finite {a. f a ≠ 1}"
assumes "(∏a. f a) ≠ 0"
shows "f a ≠ 0"
using assms Prod_any_zero [of f] by blast
lemma power_Sum_any:
assumes "finite {a. f a ≠ 0}"
shows "c ^ (∑a. f a) = (∏a. c ^ f a)"
proof -
have "{a. c ^ f a ≠ 1} ⊆ {a. f a ≠ 0}"
by (auto intro: ccontr)
with assms show ?thesis
by (simp add: Sum_any.expand_set Prod_any.expand_superset power_setsum)
qed
end