Theory SetGA
section ‹\isaheader{Generic Algorithms for Sets}›
theory SetGA
imports "../spec/SetSpec" SetIteratorCollectionsGA
begin
text_raw ‹\label{thy:SetGA}›
subsection ‹Generic Set Algorithms›
locale g_set_xx_defs_loc =
s1: StdSetDefs ops1 + s2: StdSetDefs ops2
for ops1 :: "('x,'s1,'more1) set_ops_scheme"
and ops2 :: "('x,'s2,'more2) set_ops_scheme"
begin
definition "g_copy s ≡ s1.iterate s s2.ins_dj (s2.empty ())"
definition "g_filter P s1 ≡ s1.iterate s1
(λx σ. if P x then s2.ins_dj x σ else σ)
(s2.empty ())"
definition "g_union s1 s2 ≡ s1.iterate s1 s2.ins s2"
definition "g_diff s1 s2 ≡ s2.iterate s2 s1.delete s1"
definition g_union_list where
"g_union_list l =
foldl (λs s'. g_union s' s) (s2.empty ()) l"
definition "g_union_dj s1 s2 ≡ s1.iterate s1 s2.ins_dj s2"
definition "g_disjoint_witness s1 s2 ≡
s1.sel s1 (λx. s2.memb x s2)"
definition "g_disjoint s1 s2 ≡
s1.ball s1 (λx. ¬s2.memb x s2)"
end
locale g_set_xx_loc = g_set_xx_defs_loc ops1 ops2 +
s1: StdSet ops1 + s2: StdSet ops2
for ops1 :: "('x,'s1,'more1) set_ops_scheme"
and ops2 :: "('x,'s2,'more2) set_ops_scheme"
begin
lemma g_copy_alt:
"g_copy s = iterate_to_set s2.empty s2.ins_dj (s1.iteratei s)"
unfolding iterate_to_set_alt_def g_copy_def ..
lemma g_copy_impl: "set_copy s1.α s1.invar s2.α s2.invar g_copy"
proof -
have LIS:
"set_ins_dj s2.α s2.invar s2.ins_dj"
"set_empty s2.α s2.invar s2.empty"
by unfold_locales
from iterate_to_set_correct[OF LIS s1.iteratei_correct]
show ?thesis
apply unfold_locales
unfolding g_copy_alt
by simp_all
qed
lemma g_filter_impl: "set_filter s1.α s1.invar s2.α s2.invar g_filter"
proof
fix s P
assume "s1.invar s"
hence "s2.α (g_filter P s) = {e ∈ s1.α s. P e} ∧
s2.invar (g_filter P s)" (is "?G1 ∧ ?G2")
unfolding g_filter_def
apply (rule_tac I="λit σ. s2.invar σ ∧ s2.α σ = {e ∈ it. P e}"
in s1.iterate_rule_insert_P)
by (auto simp add: s2.empty_correct s2.ins_dj_correct)
thus ?G1 ?G2 by auto
qed
lemma g_union_alt:
"g_union s1 s2 = iterate_add_to_set s2 s2.ins (s1.iteratei s1)"
unfolding iterate_add_to_set_def g_union_def ..
lemma g_diff_alt:
"g_diff s1 s2 = iterate_diff_set s1 s1.delete (s2.iteratei s2)"
unfolding g_diff_def iterate_diff_set_def ..
lemma g_union_impl:
"set_union s1.α s1.invar s2.α s2.invar s2.α s2.invar g_union"
proof -
have LIS: "set_ins s2.α s2.invar s2.ins" by unfold_locales
from iterate_add_to_set_correct[OF LIS _ s1.iteratei_correct]
show ?thesis
apply unfold_locales
unfolding g_union_alt
by simp_all
qed
lemma g_diff_impl:
"set_diff s1.α s1.invar s2.α s2.invar g_diff"
proof -
have LIS: "set_delete s1.α s1.invar s1.delete" by unfold_locales
from iterate_diff_correct[OF LIS _ s2.iteratei_correct]
show ?thesis
apply unfold_locales
unfolding g_diff_alt
by simp_all
qed
lemma g_union_list_impl:
shows "set_union_list s1.α s1.invar s2.α s2.invar g_union_list"
proof
fix l
note correct = s2.empty_correct set_union.union_correct[OF g_union_impl]
assume "∀s1∈set l. s1.invar s1"
hence aux: "⋀s. s2.invar s ⟹
s2.α (foldl (λs s'. g_union s' s) s l)
= ⋃{s1.α s1 |s1. s1 ∈ set l} ∪ s2.α s ∧
s2.invar (foldl (λs s'. g_union s' s) s l)"
by (induct l) (auto simp add: correct)
from aux [of "s2.empty ()"]
show "s2.α (g_union_list l) = ⋃{s1.α s1 |s1. s1 ∈ set l}"
"s2.invar (g_union_list l)"
unfolding g_union_list_def
by (simp_all add: correct)
qed
lemma g_union_dj_impl:
"set_union_dj s1.α s1.invar s2.α s2.invar s2.α s2.invar g_union_dj"
proof
fix s1 s2
assume I:
"s1.invar s1"
"s2.invar s2"
assume DJ: "s1.α s1 ∩ s2.α s2 = {}"
have "s2.α (g_union_dj s1 s2)
= s1.α s1 ∪ s2.α s2
∧ s2.invar (g_union_dj s1 s2)" (is "?G1 ∧ ?G2")
unfolding g_union_dj_def
apply (rule_tac I="λit σ. s2.invar σ ∧ s2.α σ = it ∪ s2.α s2"
in s1.iterate_rule_insert_P)
using DJ
apply (simp_all add: I)
apply (subgoal_tac "x∉s2.α σ")
apply (simp add: s2.ins_dj_correct I)
apply auto
done
thus ?G1 ?G2 by auto
qed
lemma g_disjoint_witness_impl:
"set_disjoint_witness s1.α s1.invar s2.α s2.invar g_disjoint_witness"
proof -
show ?thesis
apply unfold_locales
unfolding g_disjoint_witness_def
by (auto dest: s1.sel'_noneD s1.sel'_someD simp: s2.memb_correct)
qed
lemma g_disjoint_impl:
"set_disjoint s1.α s1.invar s2.α s2.invar g_disjoint"
proof -
show ?thesis
apply unfold_locales
unfolding g_disjoint_def
by (auto simp: s2.memb_correct s1.ball_correct)
qed
end
sublocale g_set_xx_loc <
set_copy s1.α s1.invar s2.α s2.invar g_copy by (rule g_copy_impl)
sublocale g_set_xx_loc <
set_filter s1.α s1.invar s2.α s2.invar g_filter by (rule g_filter_impl)
sublocale g_set_xx_loc <
set_union s1.α s1.invar s2.α s2.invar s2.α s2.invar g_union
by (rule g_union_impl)
sublocale g_set_xx_loc <
set_union_dj s1.α s1.invar s2.α s2.invar s2.α s2.invar g_union_dj
by (rule g_union_dj_impl)
sublocale g_set_xx_loc <
set_diff s1.α s1.invar s2.α s2.invar g_diff
by (rule g_diff_impl)
sublocale g_set_xx_loc <
set_disjoint_witness s1.α s1.invar s2.α s2.invar g_disjoint_witness
by (rule g_disjoint_witness_impl)
sublocale g_set_xx_loc <
set_disjoint s1.α s1.invar s2.α s2.invar g_disjoint by (rule g_disjoint_impl)
locale g_set_xxx_defs_loc =
s1: StdSetDefs ops1 +
s2: StdSetDefs ops2 +
s3: StdSetDefs ops3
for ops1 :: "('x,'s1,'more1) set_ops_scheme"
and ops2 :: "('x,'s2,'more2) set_ops_scheme"
and ops3 :: "('x,'s3,'more3) set_ops_scheme"
begin
definition "g_inter s1 s2 ≡
s1.iterate s1 (λx s. if s2.memb x s2 then s3.ins_dj x s else s)
(s3.empty ())"
end
locale g_set_xxx_loc = g_set_xxx_defs_loc ops1 ops2 ops3 +
s1: StdSet ops1 +
s2: StdSet ops2 +
s3: StdSet ops3
for ops1 :: "('x,'s1,'more1) set_ops_scheme"
and ops2 :: "('x,'s2,'more2) set_ops_scheme"
and ops3 :: "('x,'s3,'more3) set_ops_scheme"
begin
lemma g_inter_impl: "set_inter s1.α s1.invar s2.α s2.invar s3.α s3.invar
g_inter"
proof
fix s1 s2
assume I:
"s1.invar s1"
"s2.invar s2"
have "s3.α (g_inter s1 s2) = s1.α s1 ∩ s2.α s2 ∧ s3.invar (g_inter s1 s2)"
unfolding g_inter_def
apply (rule_tac I="λit σ. s3.α σ = it ∩ s2.α s2 ∧ s3.invar σ"
in s1.iterate_rule_insert_P)
apply (simp_all add: I s3.empty_correct s3.ins_dj_correct s2.memb_correct)
done
thus "s3.α (g_inter s1 s2) = s1.α s1 ∩ s2.α s2"
and "s3.invar (g_inter s1 s2)" by auto
qed
end
sublocale g_set_xxx_loc
< set_inter s1.α s1.invar s2.α s2.invar s3.α s3.invar g_inter
by (rule g_inter_impl)
locale g_set_xy_defs_loc =
s1: StdSet ops1 + s2: StdSet ops2
for ops1 :: "('x1,'s1,'more1) set_ops_scheme"
and ops2 :: "('x2,'s2,'more2) set_ops_scheme"
begin
definition "g_image_filter f s ≡
s1.iterate s
(λx res. case f x of Some v ⇒ s2.ins v res | _ ⇒ res)
(s2.empty ())"
definition "g_image f s ≡
s1.iterate s (λx res. s2.ins (f x) res) (s2.empty ())"
definition "g_inj_image_filter f s ≡
s1.iterate s
(λx res. case f x of Some v ⇒ s2.ins_dj v res | _ ⇒ res)
(s2.empty ())"
definition "g_inj_image f s ≡
s1.iterate s (λx res. s2.ins_dj (f x) res) (s2.empty ())"
end
locale g_set_xy_loc = g_set_xy_defs_loc ops1 ops2 +
s1: StdSet ops1 + s2: StdSet ops2
for ops1 :: "('x1,'s1,'more1) set_ops_scheme"
and ops2 :: "('x2,'s2,'more2) set_ops_scheme"
begin
lemma g_image_filter_impl:
"set_image_filter s1.α s1.invar s2.α s2.invar g_image_filter"
proof
fix f s
assume I: "s1.invar s"
have A: "g_image_filter f s ==
iterate_to_set s2.empty s2.ins
(set_iterator_image_filter f (s1.iteratei s))"
unfolding g_image_filter_def
iterate_to_set_alt_def set_iterator_image_filter_def
by simp
have ins: "set_ins s2.α s2.invar s2.ins"
and emp: "set_empty s2.α s2.invar s2.empty" by unfold_locales
from iterate_image_filter_to_set_correct[OF ins emp s1.iteratei_correct]
show "s2.α (g_image_filter f s) =
{b. ∃a∈s1.α s. f a = Some b}"
"s2.invar (g_image_filter f s)"
unfolding A using I by auto
qed
lemma g_image_alt: "g_image f s = g_image_filter (Some o f) s"
unfolding g_image_def g_image_filter_def
by auto
lemma g_image_impl: "set_image s1.α s1.invar s2.α s2.invar g_image"
proof -
interpret set_image_filter s1.α s1.invar s2.α s2.invar g_image_filter
by (rule g_image_filter_impl)
show ?thesis
apply unfold_locales
unfolding g_image_alt
by (auto simp add: image_filter_correct)
qed
lemma g_inj_image_filter_impl:
"set_inj_image_filter s1.α s1.invar s2.α s2.invar g_inj_image_filter"
proof
fix f::"'x1 ⇀ 'x2" and s
assume I: "s1.invar s" and INJ: "inj_on f (s1.α s ∩ dom f)"
have A: "g_inj_image_filter f s ==
iterate_to_set s2.empty s2.ins_dj
(set_iterator_image_filter f (s1.iteratei s))"
unfolding g_inj_image_filter_def
iterate_to_set_alt_def set_iterator_image_filter_def
by simp
have ins_dj: "set_ins_dj s2.α s2.invar s2.ins_dj"
and emp: "set_empty s2.α s2.invar s2.empty" by unfold_locales
from set_iterator_image_filter_correct[OF s1.iteratei_correct[OF I] INJ]
have iti_s1_filter: "set_iterator
(set_iterator_image_filter f (s1.iteratei s))
{y. ∃x. x ∈ s1.α s ∧ f x = Some y}"
by simp
from iterate_to_set_correct[OF ins_dj emp, OF iti_s1_filter]
show "s2.α (g_inj_image_filter f s) =
{b. ∃a∈s1.α s. f a = Some b}"
"s2.invar (g_inj_image_filter f s)"
unfolding A by auto
qed
lemma g_inj_image_alt: "g_inj_image f s = g_inj_image_filter (Some o f) s"
unfolding g_inj_image_def g_inj_image_filter_def
by auto
lemma g_inj_image_impl:
"set_inj_image s1.α s1.invar s2.α s2.invar g_inj_image"
proof -
interpret set_inj_image_filter
s1.α s1.invar s2.α s2.invar g_inj_image_filter
by (rule g_inj_image_filter_impl)
have AUX: "⋀S f. inj_on f S ⟹ inj_on (Some ∘ f) (S ∩ dom (Some ∘ f))"
by (auto intro!: inj_onI dest: inj_onD)
show ?thesis
apply unfold_locales
unfolding g_inj_image_alt
by (auto simp add: inj_image_filter_correct AUX)
qed
end
sublocale g_set_xy_loc < set_image_filter s1.α s1.invar s2.α s2.invar
g_image_filter by (rule g_image_filter_impl)
sublocale g_set_xy_loc < set_image s1.α s1.invar s2.α s2.invar
g_image by (rule g_image_impl)
sublocale g_set_xy_loc < set_inj_image s1.α s1.invar s2.α s2.invar
g_inj_image by (rule g_inj_image_impl)
locale g_set_xyy_defs_loc =
s0: StdSetDefs ops0 +
g_set_xx_defs_loc ops1 ops2
for ops0 :: "('x0,'s0,'more0) set_ops_scheme"
and ops1 :: "('x,'s1,'more1) set_ops_scheme"
and ops2 :: "('x,'s2,'more2) set_ops_scheme"
begin
definition g_Union_image
:: "('x0 ⇒ 's1) ⇒ 's0 ⇒ 's2"
where "g_Union_image f S
== s0.iterate S (λx res. g_union (f x) res) (s2.empty ())"
end
locale g_set_xyy_loc = g_set_xyy_defs_loc ops0 ops1 ops2 +
s0: StdSet ops0 +
g_set_xx_loc ops1 ops2
for ops0 :: "('x0,'s0,'more0) set_ops_scheme"
and ops1 :: "('x,'s1,'more1) set_ops_scheme"
and ops2 :: "('x,'s2,'more2) set_ops_scheme"
begin
lemma g_Union_image_impl:
"set_Union_image s0.α s0.invar s1.α s1.invar s2.α s2.invar g_Union_image"
proof -
{
fix s f
have "⟦s0.invar s; ⋀x. x ∈ s0.α s ⟹ s1.invar (f x)⟧ ⟹
s2.α (g_Union_image f s) = ⋃(s1.α ` f ` s0.α s)
∧ s2.invar (g_Union_image f s)"
apply (unfold g_Union_image_def)
apply (rule_tac I="λit res. s2.invar res
∧ s2.α res = ⋃(s1.α`f`(s0.α s - it))" in s0.iterate_rule_P)
apply (fastforce simp add: s2.empty_correct union_correct)+
done
}
thus ?thesis
apply unfold_locales
apply auto
done
qed
end
sublocale g_set_xyy_loc <
set_Union_image s0.α s0.invar s1.α s1.invar s2.α s2.invar g_Union_image
by (rule g_Union_image_impl)
subsection ‹Default Set Operations›