Theory Set_Algebras
section βΉAlgebraic operations on setsβΊ
theory Set_Algebras
imports Main
begin
text βΉ
This library lifts operations like addition and multiplication to sets. It
was designed to support asymptotic calculations. See the comments at the top
of πβΉBigO.thyβΊ.
βΊ
instantiation set :: (plus) plus
begin
definition plus_set :: "'a::plus set β 'a set β 'a set"
where set_plus_def: "A + B = {c. βaβA. βbβB. c = a + b}"
instance ..
end
instantiation set :: (times) times
begin
definition times_set :: "'a::times set β 'a set β 'a set"
where set_times_def: "A * B = {c. βaβA. βbβB. c = a * b}"
instance ..
end
instantiation set :: (zero) zero
begin
definition set_zero[simp]: "(0::'a::zero set) = {0}"
instance ..
end
instantiation set :: (one) one
begin
definition set_one[simp]: "(1::'a::one set) = {1}"
instance ..
end
definition elt_set_plus :: "'a::plus β 'a set β 'a set" (infixl "+o" 70)
where "a +o B = {c. βbβB. c = a + b}"
definition elt_set_times :: "'a::times β 'a set β 'a set" (infixl "*o" 80)
where "a *o B = {c. βbβB. c = a * b}"
abbreviation (input) elt_set_eq :: "'a β 'a set β bool" (infix "=o" 50)
where "x =o A β‘ x β A"
instance set :: (semigroup_add) semigroup_add
by standard (force simp add: set_plus_def add.assoc)
instance set :: (ab_semigroup_add) ab_semigroup_add
by standard (force simp add: set_plus_def add.commute)
instance set :: (monoid_add) monoid_add
by standard (simp_all add: set_plus_def)
instance set :: (comm_monoid_add) comm_monoid_add
by standard (simp_all add: set_plus_def)
instance set :: (semigroup_mult) semigroup_mult
by standard (force simp add: set_times_def mult.assoc)
instance set :: (ab_semigroup_mult) ab_semigroup_mult
by standard (force simp add: set_times_def mult.commute)
instance set :: (monoid_mult) monoid_mult
by standard (simp_all add: set_times_def)
instance set :: (comm_monoid_mult) comm_monoid_mult
by standard (simp_all add: set_times_def)
lemma set_plus_intro [intro]: "a β C βΉ b β D βΉ a + b β C + D"
by (auto simp add: set_plus_def)
lemma set_plus_elim:
assumes "x β A + B"
obtains a b where "x = a + b" and "a β A" and "b β B"
using assms unfolding set_plus_def by fast
lemma set_plus_intro2 [intro]: "b β C βΉ a + b β a +o C"
by (auto simp add: elt_set_plus_def)
lemma set_plus_rearrange: "(a +o C) + (b +o D) = (a + b) +o (C + D)"
for a b :: "'a::comm_monoid_add"
apply (auto simp add: elt_set_plus_def set_plus_def ac_simps)
apply (rule_tac x = "ba + bb" in exI)
apply (auto simp add: ac_simps)
apply (rule_tac x = "aa + a" in exI)
apply (auto simp add: ac_simps)
done
lemma set_plus_rearrange2: "a +o (b +o C) = (a + b) +o C"
for a b :: "'a::semigroup_add"
by (auto simp add: elt_set_plus_def add.assoc)
lemma set_plus_rearrange3: "(a +o B) + C = a +o (B + C)"
for a :: "'a::semigroup_add"
apply (auto simp add: elt_set_plus_def set_plus_def)
apply (blast intro: ac_simps)
apply (rule_tac x = "a + aa" in exI)
apply (rule conjI)
apply (rule_tac x = "aa" in bexI)
apply auto
apply (rule_tac x = "ba" in bexI)
apply (auto simp add: ac_simps)
done
theorem set_plus_rearrange4: "C + (a +o D) = a +o (C + D)"
for a :: "'a::comm_monoid_add"
apply (auto simp add: elt_set_plus_def set_plus_def ac_simps)
apply (rule_tac x = "aa + ba" in exI)
apply (auto simp add: ac_simps)
done
lemmas set_plus_rearranges = set_plus_rearrange set_plus_rearrange2
set_plus_rearrange3 set_plus_rearrange4
lemma set_plus_mono [intro!]: "C β D βΉ a +o C β a +o D"
by (auto simp add: elt_set_plus_def)
lemma set_plus_mono2 [intro]: "C β D βΉ E β F βΉ C + E β D + F"
for C D E F :: "'a::plus set"
by (auto simp add: set_plus_def)
lemma set_plus_mono3 [intro]: "a β C βΉ a +o D β C + D"
by (auto simp add: elt_set_plus_def set_plus_def)
lemma set_plus_mono4 [intro]: "a β C βΉ a +o D β D + C"
for a :: "'a::comm_monoid_add"
by (auto simp add: elt_set_plus_def set_plus_def ac_simps)
lemma set_plus_mono5: "a β C βΉ B β D βΉ a +o B β C + D"
apply (subgoal_tac "a +o B β a +o D")
apply (erule order_trans)
apply (erule set_plus_mono3)
apply (erule set_plus_mono)
done
lemma set_plus_mono_b: "C β D βΉ x β a +o C βΉ x β a +o D"
apply (frule set_plus_mono)
apply auto
done
lemma set_plus_mono2_b: "C β D βΉ E β F βΉ x β C + E βΉ x β D + F"
apply (frule set_plus_mono2)
prefer 2
apply force
apply assumption
done
lemma set_plus_mono3_b: "a β C βΉ x β a +o D βΉ x β C + D"
apply (frule set_plus_mono3)
apply auto
done
lemma set_plus_mono4_b: "a β C βΉ x β a +o D βΉ x β D + C"
for a x :: "'a::comm_monoid_add"
apply (frule set_plus_mono4)
apply auto
done
lemma set_zero_plus [simp]: "0 +o C = C"
for C :: "'a::comm_monoid_add set"
by (auto simp add: elt_set_plus_def)
lemma set_zero_plus2: "0 β A βΉ B β A + B"
for A B :: "'a::comm_monoid_add set"
apply (auto simp add: set_plus_def)
apply (rule_tac x = 0 in bexI)
apply (rule_tac x = x in bexI)
apply (auto simp add: ac_simps)
done
lemma set_plus_imp_minus: "a β b +o C βΉ a - b β C"
for a b :: "'a::ab_group_add"
by (auto simp add: elt_set_plus_def ac_simps)
lemma set_minus_imp_plus: "a - b β C βΉ a β b +o C"
for a b :: "'a::ab_group_add"
apply (auto simp add: elt_set_plus_def ac_simps)
apply (subgoal_tac "a = (a + - b) + b")
apply (rule bexI)
apply assumption
apply (auto simp add: ac_simps)
done
lemma set_minus_plus: "a - b β C β· a β b +o C"
for a b :: "'a::ab_group_add"
apply (rule iffI)
apply (rule set_minus_imp_plus)
apply assumption
apply (rule set_plus_imp_minus)
apply assumption
done
lemma set_times_intro [intro]: "a β C βΉ b β D βΉ a * b β C * D"
by (auto simp add: set_times_def)
lemma set_times_elim:
assumes "x β A * B"
obtains a b where "x = a * b" and "a β A" and "b β B"
using assms unfolding set_times_def by fast
lemma set_times_intro2 [intro!]: "b β C βΉ a * b β a *o C"
by (auto simp add: elt_set_times_def)
lemma set_times_rearrange: "(a *o C) * (b *o D) = (a * b) *o (C * D)"
for a b :: "'a::comm_monoid_mult"
apply (auto simp add: elt_set_times_def set_times_def)
apply (rule_tac x = "ba * bb" in exI)
apply (auto simp add: ac_simps)
apply (rule_tac x = "aa * a" in exI)
apply (auto simp add: ac_simps)
done
lemma set_times_rearrange2: "a *o (b *o C) = (a * b) *o C"
for a b :: "'a::semigroup_mult"
by (auto simp add: elt_set_times_def mult.assoc)
lemma set_times_rearrange3: "(a *o B) * C = a *o (B * C)"
for a :: "'a::semigroup_mult"
apply (auto simp add: elt_set_times_def set_times_def)
apply (blast intro: ac_simps)
apply (rule_tac x = "a * aa" in exI)
apply (rule conjI)
apply (rule_tac x = "aa" in bexI)
apply auto
apply (rule_tac x = "ba" in bexI)
apply (auto simp add: ac_simps)
done
theorem set_times_rearrange4: "C * (a *o D) = a *o (C * D)"
for a :: "'a::comm_monoid_mult"
apply (auto simp add: elt_set_times_def set_times_def ac_simps)
apply (rule_tac x = "aa * ba" in exI)
apply (auto simp add: ac_simps)
done
lemmas set_times_rearranges = set_times_rearrange set_times_rearrange2
set_times_rearrange3 set_times_rearrange4
lemma set_times_mono [intro]: "C β D βΉ a *o C β a *o D"
by (auto simp add: elt_set_times_def)
lemma set_times_mono2 [intro]: "C β D βΉ E β F βΉ C * E β D * F"
for C D E F :: "'a::times set"
by (auto simp add: set_times_def)
lemma set_times_mono3 [intro]: "a β C βΉ a *o D β C * D"
by (auto simp add: elt_set_times_def set_times_def)
lemma set_times_mono4 [intro]: "a β C βΉ a *o D β D * C"
for a :: "'a::comm_monoid_mult"
by (auto simp add: elt_set_times_def set_times_def ac_simps)
lemma set_times_mono5: "a β C βΉ B β D βΉ a *o B β C * D"
apply (subgoal_tac "a *o B β a *o D")
apply (erule order_trans)
apply (erule set_times_mono3)
apply (erule set_times_mono)
done
lemma set_times_mono_b: "C β D βΉ x β a *o C βΉ x β a *o D"
apply (frule set_times_mono)
apply auto
done
lemma set_times_mono2_b: "C β D βΉ E β F βΉ x β C * E βΉ x β D * F"
apply (frule set_times_mono2)
prefer 2
apply force
apply assumption
done
lemma set_times_mono3_b: "a β C βΉ x β a *o D βΉ x β C * D"
apply (frule set_times_mono3)
apply auto
done
lemma set_times_mono4_b: "a β C βΉ x β a *o D βΉ x β D * C"
for a x :: "'a::comm_monoid_mult"
apply (frule set_times_mono4)
apply auto
done
lemma set_one_times [simp]: "1 *o C = C"
for C :: "'a::comm_monoid_mult set"
by (auto simp add: elt_set_times_def)
lemma set_times_plus_distrib: "a *o (b +o C) = (a * b) +o (a *o C)"
for a b :: "'a::semiring"
by (auto simp add: elt_set_plus_def elt_set_times_def ring_distribs)
lemma set_times_plus_distrib2: "a *o (B + C) = (a *o B) + (a *o C)"
for a :: "'a::semiring"
apply (auto simp add: set_plus_def elt_set_times_def ring_distribs)
apply blast
apply (rule_tac x = "b + bb" in exI)
apply (auto simp add: ring_distribs)
done
lemma set_times_plus_distrib3: "(a +o C) * D β a *o D + C * D"
for a :: "'a::semiring"
apply (auto simp: elt_set_plus_def elt_set_times_def set_times_def set_plus_def ring_distribs)
apply auto
done
lemmas set_times_plus_distribs =
set_times_plus_distrib
set_times_plus_distrib2
lemma set_neg_intro: "a β (- 1) *o C βΉ - a β C"
for a :: "'a::ring_1"
by (auto simp add: elt_set_times_def)
lemma set_neg_intro2: "a β C βΉ - a β (- 1) *o C"
for a :: "'a::ring_1"
by (auto simp add: elt_set_times_def)
lemma set_plus_image: "S + T = (Ξ»(x, y). x + y) ` (S Γ T)"
by (fastforce simp: set_plus_def image_iff)
lemma set_times_image: "S * T = (Ξ»(x, y). x * y) ` (S Γ T)"
by (fastforce simp: set_times_def image_iff)
lemma finite_set_plus: "finite s βΉ finite t βΉ finite (s + t)"
by (simp add: set_plus_image)
lemma finite_set_times: "finite s βΉ finite t βΉ finite (s * t)"
by (simp add: set_times_image)
lemma set_sum_alt:
assumes fin: "finite I"
shows "sum S I = {sum s I |s. βiβI. s i β S i}"
(is "_ = ?sum I")
using fin
proof induct
case empty
then show ?case by simp
next
case (insert x F)
have "sum S (insert x F) = S x + ?sum F"
using insert.hyps by auto
also have "β¦ = {s x + sum s F |s. β iβinsert x F. s i β S i}"
unfolding set_plus_def
proof safe
fix y s
assume "y β S x" "βiβF. s i β S i"
then show "βs'. y + sum s F = s' x + sum s' F β§ (βiβinsert x F. s' i β S i)"
using insert.hyps
by (intro exI[of _ "Ξ»i. if i β F then s i else y"]) (auto simp add: set_plus_def)
qed auto
finally show ?case
using insert.hyps by auto
qed
lemma sum_set_cond_linear:
fixes f :: "'a::comm_monoid_add set β 'b::comm_monoid_add set"
assumes [intro!]: "βA B. P A βΉ P B βΉ P (A + B)" "P {0}"
and f: "βA B. P A βΉ P B βΉ f (A + B) = f A + f B" "f {0} = {0}"
assumes all: "βi. i β I βΉ P (S i)"
shows "f (sum S I) = sum (f β S) I"
proof (cases "finite I")
case True
from this all show ?thesis
proof induct
case empty
then show ?case by (auto intro!: f)
next
case (insert x F)
from βΉfinite FβΊ βΉβi. i β insert x F βΉ P (S i)βΊ have "P (sum S F)"
by induct auto
with insert show ?case
by (simp, subst f) auto
qed
next
case False
then show ?thesis by (auto intro!: f)
qed
lemma sum_set_linear:
fixes f :: "'a::comm_monoid_add set β 'b::comm_monoid_add set"
assumes "βA B. f(A) + f(B) = f(A + B)" "f {0} = {0}"
shows "f (sum S I) = sum (f β S) I"
using sum_set_cond_linear[of "Ξ»x. True" f I S] assms by auto
lemma set_times_Un_distrib:
"A * (B βͺ C) = A * B βͺ A * C"
"(A βͺ B) * C = A * C βͺ B * C"
by (auto simp: set_times_def)
lemma set_times_UNION_distrib:
"A * β(M ` I) = (βiβI. A * M i)"
"β(M ` I) * A = (βiβI. M i * A)"
by (auto simp: set_times_def)
end