(* Title: Containers/Set_Impl.thy Author:AndreasLochbihler,KIT
René Thiemann, UIBK *)
theory Set_Impl imports
Collection_Enum
DList_Set
RBT_Set2
Closure_Set
Containers_Generator
Complex_Main begin
section‹Different implementations of sets›
subsection‹Auxiliary functions›
text‹A simple quicksort implementation›
context ord begin
function (sequential) quicksort_acc :: "'a list ==> 'a list ==> 'a list" and quicksort_part :: "'a list ==> 'a ==> 'a list ==> 'a list ==> 'a list ==> 'a list ==> 'a list" where "quicksort_acc ac [] = ac"
| "quicksort_acc ac [x] = x # ac"
| "quicksort_acc ac (x # xs) = quicksort_part ac x [] [] [] xs"
| "quicksort_part ac x lts eqs gts [] = quicksort_acc (eqs @ x # quicksort_acc ac gts) lts"
| "quicksort_part ac x lts eqs gts (z # zs) = (if z > x then quicksort_part ac x lts eqs (z # gts) zs else if z < x then quicksort_part ac x (z # lts) eqs gts zs else quicksort_part ac x lts (z # eqs) gts zs)" by pat_completeness simp_all
definition quicksort :: "'a list ==> 'a list" where"quicksort = quicksort_acc []"
lemma set_quicksort_acc [simp]: "set (quicksort_acc ac xs) = set ac ∪ set xs" and set_quicksort_part [simp]: "set (quicksort_part ac x lts eqs gts zs) = set ac ∪ {x} ∪ set lts ∪ set eqs ∪ set gts ∪ set zs" by(induct ac xs and ac x lts eqs gts zs rule: quicksort_acc_quicksort_part.induct)(auto split: if_split_asm)
lemma sorted_quicksort_acc: "[ sorted ac; ∀x ∈ set xs. ∀a ∈ set ac. x < a ] ==> sorted (quicksort_acc ac xs)" and sorted_quicksort_part: "[ sorted ac; ∀y ∈ set lts ∪ {x} ∪ set eqs ∪ set gts ∪ set zs. ∀a ∈ set ac. y < a; ∀y ∈ set lts. y < x; ∀y ∈ set eqs. y = x; ∀y ∈ set gts. y > x ] ==> sorted (quicksort_part ac x lts eqs gts zs)" proof(induction ac xs and ac x lts eqs gts zs rule: quicksort_acc_quicksort_part.induct) case1thus ?caseby simp next case2thus ?caseby(auto) next case3thus ?caseby simp next case (4 ac x lts eqs gts) note ac_greater = ‹∀y∈set lts ∪ {x} ∪ set eqs ∪ set gts ∪ set []. ∀a∈set ac. y < a› have"sorted eqs""set eqs ⊆ {x}"using‹∀y∈set eqs. y = x› by(induct eqs)(simp_all) moreoverhave"∀y ∈ set ac ∪ set gts. x ≤ y" using‹∀a∈set gts. x < a› ac_greater by auto moreoverhave"sorted (quicksort_acc ac gts)" using‹sorted ac› ac_greater by(auto intro: "4.IH") ultimatelyhave"sorted (eqs @ x # quicksort_acc ac gts)" by(auto simp add: sorted_append) moreoverhave"∀y∈set lts. ∀a∈set (eqs @ x # quicksort_acc ac gts). y < a" using‹∀y∈set lts. y < x› ac_greater ‹∀a∈set gts. x < a›‹∀y∈set eqs. y = x› by fastforce ultimatelyshow ?caseby(simp add: "4.IH") next case5thus ?caseby(simp add: not_less order_eq_iff) qed
lemma insort_key_append1: "∀y ∈ set ys. f x < f y ==> insort_key f x (xs @ ys) = insort_key f x xs @ ys" proof(induct xs) case Nil thus ?caseby(cases ys) auto qed simp
lemma insort_key_append2: "∀y ∈ set xs. f x > f y ==> insort_key f x (xs @ ys) = xs @ insort_key f x ys" by(induct xs) auto
lemma sort_key_append: "∀x∈set xs. ∀y∈set ys. f x < f y ==> sort_key f (xs @ ys) = sort_key f xs @ sort_key f ys" by(induct xs)(simp_all add: insort_key_append1)
definition single_list :: "'a ==> 'a list"where"single_list a = [a]"
lemma quicksort_acc_conv_sort: "quicksort_acc ac xs = sort xs @ ac" and quicksort_part_conv_sort: "[∀y ∈ set lts. y < x; ∀y ∈ set eqs. y = x; ∀y ∈ set gts. y > x ] ==> quicksort_part ac x lts eqs gts zs = sort (lts @ eqs @ gts @ x # zs) @ ac" proof(induct ac xs and ac x lts eqs gts zs rule: quicksort_acc_quicksort_part.induct) case1thus ?caseby simp next case2thus ?caseby simp next case3thus ?caseby simp next case (4 ac x lts eqs gts) note eqs = ‹∀y∈set eqs. y = x›
{ fix eqs assume"∀y∈set eqs. y = x" hence"insort x eqs = x # eqs"by(induct eqs) simp_all } note [simp] = this from eqs have [simp]: "sort eqs = eqs"by(induct eqs) simp_all from eqs have [simp]: "eqs @ [x] = x # eqs"by(induct eqs) simp_all
show ?caseusing4 apply(subst sort_key_append) apply(auto 43 dest: bspec)[1] apply(simp add: append_assoc[symmetric] sort_snoc del: append_assoc) apply(subst sort_key_append) apply(auto 43 simp add: insort_key_append1 dest: bspec) done next case (5 ac x lts eqs gts z zs) have"[¬ z < x; ¬ x < z ]==> z = x"by simp thus ?caseusing5 apply(simp del: sort_key_simps) apply(safe, simp_all del: sort_key_simps add: to_single_list) apply(subst sort_append_swap) apply(fold append_assoc) apply(subst (2) sort_append_swap) apply(subst sort_append_swap2) apply(unfold append_assoc) apply(rule refl) apply(subst (15) append_assoc[symmetric]) apply(subst (12) sort_append_swap) apply(unfold append_assoc) apply(subst sort_append_swap2) apply(subst (12) sort_append_swap) apply(unfold append_assoc) apply(subst sort_append_swap2) apply(rule refl) apply(subst (26) append_assoc[symmetric]) apply(subst (25) append_assoc[symmetric]) apply(subst (12) sort_append_swap2) apply(subst (4) append_assoc) apply(subst (2) sort_append_swap2) apply simp done qed
fun remdups_sorted :: "'a list ==> 'a list" where "remdups_sorted [] = []"
| "remdups_sorted [x] = [x]"
| "remdups_sorted (x#y#xs) = (if x < y then x # remdups_sorted (y#xs) else remdups_sorted (y#xs))"
end
lemmas [code] = ord.remdups_sorted.simps
context linorder begin
lemma [simp]: assumes"sorted xs" shows sorted_remdups_sorted: "sorted (remdups_sorted xs)" and set_remdups_sorted: "set (remdups_sorted xs) = set xs" using assms by(induct xs rule: remdups_sorted.induct)(auto)
text‹An specialised operation to convert a finite set into a sorted list›
definition csorted_list_of_set :: "'a :: ccompare set ==> 'a list" where "csorted_list_of_set A = (if ID CCOMPARE('a) = None ∨¬ finite A then undefined else linorder.sorted_list_of_set cless_eq A)"
lemma csorted_list_of_set_set [simp]: "[ ID CCOMPARE('a :: ccompare) = Some c; linorder.sorted (le_of_comp c) xs; distinct xs ] ==> linorder.sorted_list_of_set (le_of_comp c) (set xs) = xs" by(simp add: distinct_remdups_id linorder.sorted_list_of_set_sort_remdups[OF ID_ccompare] linorder.sorted_sort_id[OF ID_ccompare])
lemma csorted_list_of_set_split: fixes A :: "'a :: ccompare set"shows "P (csorted_list_of_set A) ⟷ (∀xs. ID CCOMPARE('a) ≠ None ⟶ finite A ⟶ A = set xs ⟶ distinct xs ⟶ linorder.sorted cless_eq xs ⟶ P xs) ∧ (ID CCOMPARE('a) = None ∨¬ finite A ⟶ P undefined)" by(auto simp add: csorted_list_of_set_def linorder.sorted_list_of_set[OF ID_ccompare])
lemma comp_fun_idem_apply' [simp]: "comp_fun_idem_on UNIV (comp_fun_idem_apply f)" using comp_fun_idem_apply[of f] by (simp add: comp_fun_idem_def')
lift_definition set_fold_cfi :: "('a, 'b) comp_fun_idem ==> 'b ==> 'a set ==> 'b"is"Finite_Set.fold" .
lemma set_fold_cfi_code [code]: fixes xs :: "'a list" and dxs :: "'b :: ceq set_dlist" and rbt :: "'c :: ccompare set_rbt" shows "set_fold_cfi f'' b (RBT_set rbt) = (case ID CCOMPARE('c) of None ==> Code.abort (STR ''set_fold_cfi RBT_set: ccompare = None'') (λ_. set_fold_cfi f'' b (RBT_set rbt)) | Some _ ==> RBT_Set2.fold (comp_fun_idem_apply f'') rbt b)"
(is ?RBT_set) "set_fold_cfi f' b (DList_set dxs) = (case ID CEQ('b) of None ==> Code.abort (STR ''set_fold_cfi DList_set: ceq = None'') (λ_. set_fold_cfi f' b (DList_set dxs)) | Some _ ==> DList_Set.fold (comp_fun_idem_apply f') dxs b)"
(is ?DList_set) "set_fold_cfi f b (Set_Monad xs) = List.fold (comp_fun_idem_apply f) xs b"
(is ?Set_Monad) "set_fold_cfi f b (Collect_set P) = Code.abort (STR ''set_fold_cfi not supported on Collect_set'') (λ_. set_fold_cfi f b (Collect_set P))" "set_fold_cfi f b (Complement A) = Code.abort (STR ''set_fold_cfi not supported on Complement'') (λ_. set_fold_cfi f b (Complement A))" proof - show ?Set_Monad by(auto split: option.split dest!: Collection_Eq.ID_ceq simp add: set_fold_cfi_def comp_fun_idem_def' comp_fun_idem_on.fold_set_fold[OF _ subset_UNIV]) show ?DList_set apply(auto split: option.split simp add: DList_set_def) apply transfer apply(auto dest: Collection_Eq.ID_ceq simp add: List.member_iff [abs_def] comp_fun_idem_def' comp_fun_idem_on.fold_set_fold[OF _ subset_UNIV]) done show ?RBT_set apply(auto split: option.split simp add: RBT_set_conv_keys fold_conv_fold_keys) apply transfer apply(simp add: comp_fun_idem_def' comp_fun_idem_on.fold_set_fold[OF _ subset_UNIV]) done qed simp_all
typedef 'a semilattice_set = "{f :: 'a ==> 'a ==> 'a. semilattice_set f}" morphisms semilattice_set_apply Abs_semilattice_set proof show"(λx y. if x = y then x else undefined) ∈ ?semilattice_set" unfolding mem_Collect_eq by(unfold_locales) simp_all qed
setup_lifting type_definition_semilattice_set
lemma semilattice_set_apply' [simp]: "semilattice_set (semilattice_set_apply f)" using semilattice_set_apply[of f] by simp
lift_definition set_fold1 :: "'a semilattice_set ==> 'a set ==> 'a"is"semilattice_set.F" .
lemma (in semilattice_set) F_set_conv_fold: "xs ≠ [] ==> F (set xs) = Finite_Set.fold f (hd xs) (set (tl xs))" by(clarsimp simp add: neq_Nil_conv eq_fold)
lemma set_fold1_code [code]: fixes rbt :: "'a :: {ccompare, lattice} set_rbt" and dxs :: "'b :: {ceq, lattice} set_dlist" shows [set_base_code]: "set_fold1 f'' (RBT_set rbt) = (case ID CCOMPARE('a) of None ==> Code.abort (STR ''set_fold1 RBT_set: ccompare = None'') (λ_. set_fold1 f'' (RBT_set rbt)) | Some _ ==> if RBT_Set2.is_empty rbt then Code.abort (STR ''set_fold1 RBT_set: empty set'') (λ_. set_fold1 f'' (RBT_set rbt)) else RBT_Set2.fold1 (semilattice_set_apply f'') rbt)"
(is"?RBT_set") "set_fold1 f' (DList_set dxs) = (case ID CEQ('b) of None ==> Code.abort (STR ''set_fold1 DList_set: ceq = None'') (λ_. set_fold1 f' (DList_set dxs)) | Some _ ==> if DList_Set.null dxs then Code.abort (STR ''set_fold1 DList_set: empty set'') (λ_. set_fold1 f' (DList_set dxs)) else DList_Set.fold (semilattice_set_apply f') (DList_Set.tl dxs) (DList_Set.hd dxs))"
(is"?DList_set") "set_fold1 f (Set_Monad (x # xs)) = fold (semilattice_set_apply f) xs x"
(is"?Set_Monad") "set_fold1 f (Collect_set P) = Code.abort (STR ''set_fold1: Collect_set'') (λ_. set_fold1 f (Collect_set P))" and set_fold1_Complement: "set_fold1 f (Complement A) = Code.abort (STR ''set_fold1: Complement'') (λ_. set_fold1 f (Complement A))" proof - note fold_set_fold = comp_fun_idem_def' comp_fun_idem_on.fold_set_fold[OF _ subset_UNIV] show ?Set_Monad by(simp add: set_fold1_def semilattice_set.eq_fold fold_set_fold) show ?DList_set by(simp add: set_fold1_def semilattice_set.F_set_conv_fold fold_set_fold DList_set_def DList_Set.Collect_member split: option.split)(transfer, simp) show ?RBT_set by(simp add: set_fold1_def semilattice_set.F_set_conv_fold fold_set_fold RBT_set_def RBT_Set2.member_conv_keys RBT_Set2.fold1_conv_fold split: option.split) qed simp_all
text‹Implementation of set operations›
lemma Collect_code [code, set_base_code]: fixes P :: "'a :: cenum ==> bool"shows "Collect P = (case ID CENUM('a) of None ==> Collect_set P | Some (enum, _) ==> Set_Monad (filter P enum))" by(auto split: option.split dest: in_cenum)
lemma finite_code [code]: fixes dxs :: "'a :: ceq set_dlist" and rbt :: "'b :: ccompare set_rbt" and A :: "'c :: finite_UNIV set"and P :: "'c ==> bool" shows [set_base_code]: "finite (Collect_set P) ⟷ of_phantom (finite_UNIV :: 'c finite_UNIV) ∨ Code.abort (STR ''finite Collect_set'') (λ_. finite (Collect_set P))" "finite (Set_Monad xs) = True" and finite_Complement: "finite (Complement A) ⟷ (if of_phantom (finite_UNIV :: 'c finite_UNIV) then True else if finite A then False else Code.abort (STR ''finite Complement: infinite set'') (λ_. finite (Complement A)))" and [set_base_code]: "finite (RBT_set rbt) = (case ID CCOMPARE('b) of None ==> Code.abort (STR ''finite RBT_set: ccompare = None'') (λ_. finite (RBT_set rbt)) | Some _ ==> True)" "finite (DList_set dxs) = (case ID CEQ('a) of None ==> Code.abort (STR ''finite DList_set: ceq = None'') (λ_. finite (DList_set dxs)) | Some _ ==> True)" by (auto simp add: DList_set_def RBT_set_def member_conv_keys card_gt_0_iff finite_UNIV split: option.split elim: finite_subset [rotated 1])
lemma CARD_code [code_unfold]: "CARD('a :: card_UNIV) = of_phantom (card_UNIV :: 'a card_UNIV)" by (simp add: card_UNIV)
lemma card_code [code]: fixes dxs :: "'a :: ceq set_dlist"and xs :: "'a list" and rbt :: "'b :: ccompare set_rbt" and A :: "'c :: card_UNIV set" shows card_Complement: "card (Complement A) = (let a = card A; s = CARD('c) in if s > 0 then s - a else if finite A then 0 else Code.abort (STR ''card Complement: infinite'') (λ_. card (Complement A)))"
and [set_base_code]: "card (Set_Monad xs) = (case ID CEQ('a) of None ==> Code.abort (STR ''card Set_Monad: ceq = None'') (λ_. card (Set_Monad xs)) | Some eq ==> length (equal_base.list_remdups eq xs))" "card (RBT_set rbt) = (case ID CCOMPARE('b) of None ==> Code.abort (STR ''card RBT_set: ccompare = None'') (λ_. card (RBT_set rbt)) | Some _ ==> length (RBT_Set2.keys rbt))" "card (DList_set dxs) = (case ID CEQ('a) of None ==> Code.abort (STR ''card DList_set: ceq = None'') (λ_. card (DList_set dxs)) | Some _ ==> DList_Set.length dxs)" by(auto simp add: RBT_set_def member_conv_keys distinct_card DList_set_def Let_def card_UNIV Compl_eq_Diff_UNIV card_Diff_subset_Int card_gt_0_iff finite_subset[of A UNIV] List.card_set dest: Collection_Eq.ID_ceq split: option.split)
lemma is_UNIV_code [code, set_base_code]: fixes rbt :: "'a :: {cproper_interval, finite_UNIV} set_rbt" and A :: "'b :: card_UNIV set" shows "is_UNIV (RBT_set rbt) = (case ID CCOMPARE('a) of None ==> Code.abort (STR ''is_UNIV RBT_set: ccompare = None'') (λ_. is_UNIV (RBT_set rbt)) | Some _ ==> of_phantom (finite_UNIV :: 'a finite_UNIV) ∧ proper_intrvl.exhaustive_fusion cproper_interval rbt_keys_generator (RBT_Set2.init rbt))"
(is ?rbt) "is_UNIV A ⟷ (let a = CARD('b); b = card A in if a > 0 then a = b else if b > 0 then False else Code.abort (STR ''is_UNIV called on infinite type and set'') (λ_. is_UNIV A))"
(is ?generic) proof -
{ fix c assume linorder: "ID CCOMPARE('a) = Some c" have"is_UNIV (RBT_set rbt) = (finite (UNIV :: 'a set) ∧ proper_intrvl.exhaustive cproper_interval (RBT_Set2.keys rbt))"
(is"?lhs ⟷ ?rhs") proof assume ?lhs have"finite (UNIV :: 'a set)" unfolding‹?lhs›[unfolded is_UNIV_def, symmetric] using linorder by(simp add: finite_code) moreover hence"proper_intrvl.exhaustive cproper_interval (RBT_Set2.keys rbt)" using linorder ‹?lhs› by(simp add: linorder_proper_interval.exhaustive_correct[OF ID_ccompare_interval[OF linorder]] sorted_RBT_Set_keys is_UNIV_def RBT_set_conv_keys) ultimatelyshow ?rhs .. next assume ?rhs thus ?lhs using linorder by(auto simp add: linorder_proper_interval.exhaustive_correct[OF ID_ccompare_interval[OF linorder]] sorted_RBT_Set_keys is_UNIV_def RBT_set_conv_keys) qed } thus ?rbt by(auto simp add: finite_UNIV proper_intrvl.exhaustive_fusion_def unfoldr_rbt_keys_generator is_UNIV_def split: option.split)
show ?generic by(auto simp add: Let_def is_UNIV_def dest: card_seteq[of UNIV A] dest!: card_ge_0_finite) qed
lemma is_empty_code [code]: fixes dxs :: "'a :: ceq set_dlist" and rbt :: "'b :: ccompare set_rbt" and A :: "'c set" shows is_empty_Complement: "Set.is_empty (Complement A) ⟷ is_UNIV A"
(is ?Complement) and [set_base_code]: "Set.is_empty (RBT_set rbt) ⟷ (case ID CCOMPARE('b) of None ==> Code.abort (STR ''is_empty RBT_set: ccompare = None'') (λ_. Set.is_empty (RBT_set rbt)) | Some _ ==> RBT_Set2.is_empty rbt)"
(is ?RBT_set) "Set.is_empty (DList_set dxs) ⟷ (case ID CEQ('a) of None ==> Code.abort (STR ''is_empty DList_set: ceq = None'') (λ_. Set.is_empty (DList_set dxs)) | Some _ ==> DList_Set.null dxs)"
(is ?DList_set) "Set.is_empty (Set_Monad xs) ⟷ xs = []" proof - show ?DList_set by(clarsimp simp add: DList_set_def DList_Set.member_empty_empty split: option.split)
show ?Complement by(auto simp add: is_UNIV_def) qed simp_all
lemma Set_insert_code [code]: fixes dxs :: "'a :: ceq set_dlist" and rbt :: "'b :: ccompare set_rbt" shows insert_Complement: "∧x. Set.insert x (Complement X) = Complement (Set.remove x X)" and [set_base_code]: "∧x. Set.insert x (RBT_set rbt) = (case ID CCOMPARE('b) of None ==> Code.abort (STR ''insert RBT_set: ccompare = None'') (λ_. Set.insert x (RBT_set rbt)) | Some _ ==> RBT_set (RBT_Set2.insert x rbt))" "∧x. Set.insert x (DList_set dxs) = (case ID CEQ('a) of None ==> Code.abort (STR ''insert DList_set: ceq = None'') (λ_. Set.insert x (DList_set dxs)) | Some _ ==> DList_set (DList_Set.insert x dxs))" "∧x. Set.insert x (Set_Monad xs) = Set_Monad (x # xs)" "∧x. Set.insert x (Collect_set A) = (case ID CEQ('a) of None ==> Code.abort (STR ''insert Collect_set: ceq = None'') (λ_. Set.insert x (Collect_set A)) | Some eq ==> Collect_set (equal_base.fun_upd eq A x True))" by(auto split: option.split dest: equal.equal_eq[OF ID_ceq] simp add: DList_set_def DList_Set.member_insert RBT_set_def)
lemma Set_member_code [code]: fixes xs :: "'a :: ceq list" shows [set_base_code]: "∧x. x ∈ Set_Monad xs ⟷ (case ID CEQ('a) of None ==> Code.abort (STR ''member Set_Monad: ceq = None'') (λ_. x ∈ Set_Monad xs) | Some eq ==> equal_base.list_member eq xs x)" and mem_Complement: "∧x. x ∈ Complement X ⟷ x ∉ X" and [set_base_code]: "∧x. x ∈ RBT_set rbt ⟷ RBT_Set2.member rbt x" "∧x. x ∈ DList_set dxs ⟷ DList_Set.member dxs x" "∧x. x ∈ Collect_set A ⟷ A x" by(auto simp add: DList_set_def RBT_set_def split: option.split dest!: Collection_Eq.ID_ceq)
lemma Set_remove_code [code]: fixes rbt :: "'a :: ccompare set_rbt" and dxs :: "'b :: ceq set_dlist" shows remove_Complement: "∧x A. Set.remove x (Complement A) = Complement (Set.insert x A)" and [set_base_code]: "∧x. Set.remove x (RBT_set rbt) = (case ID CCOMPARE('a) of None ==> Code.abort (STR ''remove RBT_set: ccompare = None'') (λ_. Set.remove x (RBT_set rbt)) | Some _ ==> RBT_set (RBT_Set2.remove x rbt))" "∧x. Set.remove x (DList_set dxs) = (case ID CEQ('b) of None ==> Code.abort (STR ''remove DList_set: ceq = None'') (λ_. Set.remove x (DList_set dxs)) | Some _ ==> DList_set (DList_Set.remove x dxs))" "∧x. Set.remove x (Collect_set A) = (case ID CEQ('b) of None ==> Code.abort (STR ''remove Collect: ceq = None'') (λ_. Set.remove x (Collect_set A)) | Some eq ==> Collect_set (equal_base.fun_upd eq A x False))" by(auto split: option.split if_split_asm dest: equal.equal_eq[OF ID_ceq] simp add: DList_set_def DList_Set.member_remove RBT_set_def)
lemma Set_uminus_code [code]: "- (Complement B) = B" "- (Collect_set P) = Collect_set (λx. ¬ P x)" "- A = Complement A" by auto
text‹
These equations represent complements as true complements.
If you want that the complement operations returns an explicit enumeration of the elements, use the following set of equations which use @{class cenum}. ›
lemma Set_uminus_cenum: fixes A :: "'a :: cenum set" shows"- A = (case ID CENUM('a) of None ==> Complement A | Some (enum, _) ==> Set_Monad (filter (λx. x ∉ A) enum))" and"- (Complement B) = B" by(auto split: option.split dest: ID_cEnum)
lemma Set_minus_code [code, set_base_code]: fixes rbt1 rbt2 :: "'a :: ccompare set_rbt" shows "RBT_set rbt1 - RBT_set rbt2 = (case ID CCOMPARE('a) of None ==> Code.abort (STR ''minus RBT_set RBT_set: ccompare = None'') (λ_. RBT_set rbt1 - RBT_set rbt2) | Some _ ==> RBT_set (RBT_Set2.minus rbt1 rbt2))" "A - B = A ∩ (- B)" by (auto simp: Set_member_code(3) split: option.splits)
lemma Set_union_code [code]: fixes rbt1 rbt2 :: "'a :: ccompare set_rbt" and rbt :: "'b :: {ccompare, ceq} set_rbt" and dxs :: "'b set_dlist" and dxs1 dxs2 :: "'c :: ceq set_dlist" shows Set_union_Complement: "B' ∪ Complement B = Complement (- B' ∩ B)" "Complement B ∪ B' = Complement (B ∩ - B')" and [set_base_code]: "RBT_set rbt1 ∪ RBT_set rbt2 = (case ID CCOMPARE('a) of None ==> Code.abort (STR ''union RBT_set RBT_set: ccompare = None'') (λ_. RBT_set rbt1 ∪ RBT_set rbt2) | Some _ ==> RBT_set (RBT_Set2.union rbt1 rbt2))" (is ?RBT_set_RBT_set) "RBT_set rbt ∪ DList_set dxs = (case ID CCOMPARE('b) of None ==> Code.abort (STR ''union RBT_set DList_set: ccompare = None'') (λ_. RBT_set rbt ∪ DList_set dxs) | Some _ ==> case ID CEQ('b) of None ==> Code.abort (STR ''union RBT_set DList_set: ceq = None'') (λ_. RBT_set rbt ∪ DList_set dxs) | Some _ ==> RBT_set (DList_Set.fold RBT_Set2.insert dxs rbt))" (is ?RBT_set_DList_set) "DList_set dxs ∪ RBT_set rbt = (case ID CCOMPARE('b) of None ==> Code.abort (STR ''union DList_set RBT_set: ccompare = None'') (λ_. RBT_set rbt ∪ DList_set dxs) | Some _ ==> case ID CEQ('b) of None ==> Code.abort (STR ''union DList_set RBT_set: ceq = None'') (λ_. RBT_set rbt ∪ DList_set dxs) | Some _ ==> RBT_set (DList_Set.fold RBT_Set2.insert dxs rbt))" (is ?DList_set_RBT_set) "DList_set dxs1 ∪ DList_set dxs2 = (case ID CEQ('c) of None ==> Code.abort (STR ''union DList_set DList_set: ceq = None'') (λ_. DList_set dxs1 ∪ DList_set dxs2) | Some _ ==> DList_set (DList_Set.union dxs1 dxs2))" (is ?DList_set_DList_set) "Set_Monad zs ∪ RBT_set rbt2 = (case ID CCOMPARE('a) of None ==> Code.abort (STR ''union Set_Monad RBT_set: ccompare = None'') (λ_. Set_Monad zs ∪ RBT_set rbt2) | Some _ ==> RBT_set (fold RBT_Set2.insert zs rbt2))" (is ?Set_Monad_RBT_set) "RBT_set rbt1 ∪ Set_Monad zs = (case ID CCOMPARE('a) of None ==> Code.abort (STR ''union RBT_set Set_Monad: ccompare = None'') (λ_. RBT_set rbt1 ∪ Set_Monad zs) | Some _ ==> RBT_set (fold RBT_Set2.insert zs rbt1))" (is ?RBT_set_Set_Monad) "Set_Monad ws ∪ DList_set dxs2 = (case ID CEQ('c) of None ==> Code.abort (STR ''union Set_Monad DList_set: ceq = None'') (λ_. Set_Monad ws ∪ DList_set dxs2) | Some _ ==> DList_set (fold DList_Set.insert ws dxs2))" (is ?Set_Monad_DList_set) "DList_set dxs1 ∪ Set_Monad ws = (case ID CEQ('c) of None ==> Code.abort (STR ''union DList_set Set_Monad: ceq = None'') (λ_. DList_set dxs1 ∪ Set_Monad ws) | Some _ ==> DList_set (fold DList_Set.insert ws dxs1))" (is ?DList_set_Set_Monad) "Set_Monad xs ∪ Set_Monad ys = Set_Monad (xs @ ys)" "B ∪ Collect_set A = Collect_set (λx. A x ∨ x ∈ B)" "Collect_set A ∪ B = Collect_set (λx. A x ∨ x ∈ B)" proof - show ?RBT_set_RBT_set ?Set_Monad_RBT_set ?RBT_set_Set_Monad by(auto split: option.split simp add: RBT_set_def)
lemma Inf_code: fixes A :: "'a :: complete_lattice set" shows"Inf A = (if finite A then set_fold_cfi inf_cfi top A else Code.abort (STR ''Inf: infinite'') (λ_. Inf A))" by transfer (simp add: Inf_fold_inf)
lemma Sup_code: fixes A :: "'a :: complete_lattice set" shows"Sup A = (if finite A then set_fold_cfi sup_cfi bot A else Code.abort (STR ''Sup: infinite'') (λ_. Sup A))" by transfer (simp add: Sup_fold_sup)
lift_definition min_sls :: "'a :: linorder semilattice_set" is min
..
lemma Min_code [code, set_base_code]: "Min A = set_fold1 min_sls A" by transfer (simp add: Min_def)
lift_definition max_sls :: "'a :: linorder semilattice_set" is max
..
lemma Max_code [code, set_base_code]: "Max A = set_fold1 max_sls A" by transfer (simp add: Max_def)
text‹
We do not implement @{term Ball}, @{term Bex}, and @{term sorted_list_of_set} for @{term Collect_set} using @{term cEnum},
because it should already have been converted to an explicit list of elements if that is possible. ›
lemma Ball_code [code, set_base_code]: fixes rbt :: "'a :: ccompare set_rbt" and dxs :: "'b :: ceq set_dlist" shows "Ball (RBT_set rbt) P'' = (case ID CCOMPARE('a) of None ==> Code.abort (STR ''Ball RBT_set: ccompare = None'') (λ_. Ball (RBT_set rbt) P'') | Some _ ==> RBT_Set2.all P'' rbt)" "Ball (DList_set dxs) P' = (case ID CEQ('b) of None ==> Code.abort (STR ''Ball DList_set: ceq = None'') (λ_. Ball (DList_set dxs) P') | Some _ ==> DList_Set.dlist_all P' dxs)" "Ball (Set_Monad xs) P = list_all P xs" by (simp_all add: DList_set_def RBT_set_def list_all_iff dlist_all_conv_member RBT_Set2.all_conv_all_member split: option.splits)
lemma Bex_code [code, set_base_code]: fixes rbt :: "'a :: ccompare set_rbt" and dxs :: "'b :: ceq set_dlist" shows "Bex (RBT_set rbt) P'' = (case ID CCOMPARE('a) of None ==> Code.abort (STR ''Bex RBT_set: ccompare = None'') (λ_. Bex (RBT_set rbt) P'') | Some _ ==> RBT_Set2.ex P'' rbt)" "Bex (DList_set dxs) P' = (case ID CEQ('b) of None ==> Code.abort (STR ''Bex DList_set: ceq = None'') (λ_. Bex (DList_set dxs) P') | Some _ ==> DList_Set.dlist_ex P' dxs)" "Bex (Set_Monad xs) P = list_ex P xs" by (simp_all add: DList_set_def RBT_set_def list_ex_iff dlist_ex_conv_member RBT_Set2.ex_conv_ex_member split: option.splits)
lemma csorted_list_of_set_code [code, set_base_code]: fixes rbt :: "'a :: ccompare set_rbt" and dxs :: "'b :: {ccompare, ceq} set_dlist" and xs :: "'a :: ccompare list" shows "csorted_list_of_set (Set_Monad xs) = (case ID CCOMPARE('a) of None ==> Code.abort (STR ''csorted_list_of_set Set_Monad: ccompare = None'') (λ_. csorted_list_of_set (Set_Monad xs)) | Some c ==> ord.remdups_sorted (lt_of_comp c) (ord.quicksort (lt_of_comp c) xs))" "csorted_list_of_set (DList_set dxs) = (case ID CEQ('b) of None ==> Code.abort (STR ''csorted_list_of_set DList_set: ceq = None'') (λ_. csorted_list_of_set (DList_set dxs)) | Some _ ==> case ID CCOMPARE('b) of None ==> Code.abort (STR ''csorted_list_of_set DList_set: ccompare = None'') (λ_. csorted_list_of_set (DList_set dxs)) | Some c ==> ord.quicksort (lt_of_comp c) (list_of_dlist dxs))" "csorted_list_of_set (RBT_set rbt) = (case ID CCOMPARE('a) of None ==> Code.abort (STR ''csorted_list_of_set RBT_set: ccompare = None'') (λ_. csorted_list_of_set (RBT_set rbt)) | Some _ ==> RBT_Set2.keys rbt)" by (auto split: option.split simp add: RBT_set_def DList_set_def DList_Set.Collect_member member_conv_keys sorted_RBT_Set_keys linorder.sorted_list_of_set_sort_remdups[OF ID_ccompare] linorder.quicksort_conv_sort[OF ID_ccompare] distinct_remdups_id distinct_list_of_dlist linorder.remdups_sorted_conv_remdups[OF ID_ccompare] linorder.sorted_sort[OF ID_ccompare] linorder.sort_remdups[OF ID_ccompare] csorted_list_of_set_def)
lemma cless_set_code [code]: fixes rbt rbt' :: "'a :: ccompare set_rbt" and rbt1 rbt2 :: "'b :: cproper_interval set_rbt" and A B :: "'a set" and A' B' :: "'b set" shows cless_set_rbt_Complement1: "cless_set (Complement (RBT_set rbt1)) (RBT_set rbt2) ⟷ (case ID CCOMPARE('b) of None ==> Code.abort (STR ''cless_set (Complement RBT_set) RBT_set: ccompare = None'') (λ_. cless_set (Complement (RBT_set rbt1)) (RBT_set rbt2)) | Some c ==> finite (UNIV :: 'b set) ∧ proper_intrvl.Compl_set_less_aux_fusion (lt_of_comp c) cproper_interval rbt_keys_generator rbt_keys_generator None (RBT_Set2.init rbt1) (RBT_Set2.init rbt2))"
(is ?Compl_rbt) and cless_set_rbt_Complement2: "cless_set (RBT_set rbt1) (Complement (RBT_set rbt2)) ⟷ (case ID CCOMPARE('b) of None ==> Code.abort (STR ''cless_set RBT_set (Complement RBT_set): ccompare = None'') (λ_. cless_set (RBT_set rbt1) (Complement (RBT_set rbt2))) | Some c ==> finite (UNIV :: 'b set) ⟶ proper_intrvl.set_less_aux_Compl_fusion (lt_of_comp c) cproper_interval rbt_keys_generator rbt_keys_generator None (RBT_Set2.init rbt1) (RBT_Set2.init rbt2))"
(is ?rbt_Compl) and [set_base_code]: "cless_set (RBT_set rbt) (RBT_set rbt') ⟷ (case ID CCOMPARE('a) of None ==> Code.abort (STR ''cless_set RBT_set RBT_set: ccompare = None'') (λ_. cless_set (RBT_set rbt) (RBT_set rbt')) | Some c ==> ord.lexord_fusion (λx y. lt_of_comp c y x) rbt_keys_generator rbt_keys_generator (RBT_Set2.init rbt) (RBT_Set2.init rbt'))"
(is ?rbt_rbt) and cless_set_Complement12: "cless_set (Complement A) (Complement B) ⟷ (case ID CCOMPARE('a) of None ==> Code.abort (STR ''cless_set Complement Complement: ccompare = None'') (λ_. cless_set (Complement A) (Complement B)) | Some _ ==> cless B A)"
(is ?Compl_Compl) and cless_set_Complement1: "cless_set (Complement A') B' ⟷ (case ID CCOMPARE('b) of None ==> Code.abort (STR ''cless_set Complement1: ccompare = None'') (λ_. cless_set (Complement A') B') | Some c ==> if finite A' ∧ finite B' then finite (UNIV :: 'b set) ∧ proper_intrvl.Compl_set_less_aux (lt_of_comp c) cproper_interval None (csorted_list_of_set A') (csorted_list_of_set B') else Code.abort (STR ''cless_set Complement1: infinite set'') (λ_. cless_set (Complement A') B'))"
(is"?Compl_fin_fin") and cless_set_Complement2: "cless_set A' (Complement B') ⟷ (case ID CCOMPARE('b) of None ==> Code.abort (STR ''cless_set Complement2: ccompare = None'') (λ_. cless_set A' (Complement B')) | Some c ==> if finite A' ∧ finite B' then finite (UNIV :: 'b set) ⟶ proper_intrvl.set_less_aux_Compl (lt_of_comp c) cproper_interval None (csorted_list_of_set A') (csorted_list_of_set B') else Code.abort (STR ''cless_set Complement2: infinite set'') (λ_. cless_set A' (Complement B')))"
(is"?fin_Compl_fin") and [set_base_code]: "cless_set A B ⟷ (case ID CCOMPARE('a) of None ==> Code.abort (STR ''cless_set: ccompare = None'') (λ_. cless_set A B) | Some c ==> if finite A ∧ finite B then ord.lexordp (λx y. lt_of_comp c y x) (csorted_list_of_set A) (csorted_list_of_set B) else Code.abort (STR ''cless_set: infinite set'') (λ_. cless_set A B))"
(is"?fin_fin") proof - note [split] = option.split csorted_list_of_set_split and [simp] =
le_of_comp_of_ords_linorder[OF ID_ccompare]
lt_of_comp_of_ords
finite_subset[OF subset_UNIV] ccompare_set_def ID_Some
ord.lexord_fusion_def
proper_intrvl.Compl_set_less_aux_fusion_def
proper_intrvl.set_less_aux_Compl_fusion_def
unfoldr_rbt_keys_generator
RBT_set_def sorted_RBT_Set_keys member_conv_keys
linorder.set_less_finite_iff[OF ID_ccompare]
linorder.set_less_aux_code[OF ID_ccompare, symmetric]
linorder.Compl_set_less_Compl[OF ID_ccompare]
linorder.infinite_set_less_Complement[OF ID_ccompare]
linorder.infinite_Complement_set_less[OF ID_ccompare]
linorder_proper_interval.set_less_aux_Compl2_conv_set_less_aux_Compl[OF ID_ccompare_interval, symmetric]
linorder_proper_interval.Compl1_set_less_aux_conv_Compl_set_less_aux[OF ID_ccompare_interval, symmetric]
show ?Compl_Compl by simp show ?rbt_rbt by auto show ?rbt_Compl by(cases "finite (UNIV :: 'b set)") auto show ?Compl_rbt by(cases "finite (UNIV :: 'b set)") auto show ?fin_fin by auto show ?fin_Compl_fin by(cases "finite (UNIV :: 'b set)", auto) show ?Compl_fin_fin by(cases "finite (UNIV :: 'b set)") auto qed
lemma cless_eq_set_code [code]: fixes rbt rbt' :: "'a :: ccompare set_rbt" and rbt1 rbt2 :: "'b :: cproper_interval set_rbt" and A B :: "'a set" and A' B' :: "'b set" shows cless_eq_set_rbt_Complement1: "cless_eq_set (Complement (RBT_set rbt1)) (RBT_set rbt2) ⟷ (case ID CCOMPARE('b) of None ==> Code.abort (STR ''cless_eq_set (Complement RBT_set) RBT_set: ccompare = None'') (λ_. cless_eq_set (Complement (RBT_set rbt1)) (RBT_set rbt2)) | Some c ==> finite (UNIV :: 'b set) ∧ proper_intrvl.Compl_set_less_eq_aux_fusion (lt_of_comp c) cproper_interval rbt_keys_generator rbt_keys_generator None (RBT_Set2.init rbt1) (RBT_Set2.init rbt2))"
(is ?Compl_rbt) and cless_eq_set_rbt_Complement2: "cless_eq_set (RBT_set rbt1) (Complement (RBT_set rbt2)) ⟷ (case ID CCOMPARE('b) of None ==> Code.abort (STR ''cless_eq_set RBT_set (Complement RBT_set): ccompare = None'') (λ_. cless_eq_set (RBT_set rbt1) (Complement (RBT_set rbt2))) | Some c ==> finite (UNIV :: 'b set) ⟶ proper_intrvl.set_less_eq_aux_Compl_fusion (lt_of_comp c) cproper_interval rbt_keys_generator rbt_keys_generator None (RBT_Set2.init rbt1) (RBT_Set2.init rbt2))"
(is ?rbt_Compl) and [set_base_code]: "cless_eq_set (RBT_set rbt) (RBT_set rbt') ⟷ (case ID CCOMPARE('a) of None ==> Code.abort (STR ''cless_eq_set RBT_set RBT_set: ccompare = None'') (λ_. cless_eq_set (RBT_set rbt) (RBT_set rbt')) | Some c ==> ord.lexord_eq_fusion (λx y. lt_of_comp c y x) rbt_keys_generator rbt_keys_generator (RBT_Set2.init rbt) (RBT_Set2.init rbt'))"
(is ?rbt_rbt) and cless_eq_set_Complement12: "cless_eq_set (Complement A) (Complement B) ⟷ (case ID CCOMPARE('a) of None ==> Code.abort (STR ''cless_eq_set Complement Complement: ccompare = None'') (λ_. cless_eq (Complement A) (Complement B)) | Some c ==> cless_eq_set B A)"
(is ?Compl_Compl) and cless_eq_set_Complement1: "cless_eq_set (Complement A') B' ⟷ (case ID CCOMPARE('b) of None ==> Code.abort (STR ''cless_eq_set Complement1: ccompare = None'') (λ_. cless_eq_set (Complement A') B') | Some c ==> if finite A' ∧ finite B' then finite (UNIV :: 'b set) ∧ proper_intrvl.Compl_set_less_eq_aux (lt_of_comp c) cproper_interval None (csorted_list_of_set A') (csorted_list_of_set B') else Code.abort (STR ''cless_eq_set Complement1: infinite set'') (λ_. cless_eq_set (Complement A') B'))"
(is"?Compl_fin_fin") and cless_eq_set_Complement2: "cless_eq_set A' (Complement B') ⟷ (case ID CCOMPARE('b) of None ==> Code.abort (STR ''cless_eq_set Complement2: ccompare = None'') (λ_. cless_eq_set A' (Complement B')) | Some c ==> if finite A' ∧ finite B' then finite (UNIV :: 'b set) ⟶ proper_intrvl.set_less_eq_aux_Compl (lt_of_comp c) cproper_interval None (csorted_list_of_set A') (csorted_list_of_set B') else Code.abort (STR ''cless_eq_set Complement2: infinite set'') (λ_. cless_eq_set A' (Complement B')))"
(is"?fin_Compl_fin") and [set_base_code]: "cless_eq_set A B ⟷ (case ID CCOMPARE('a) of None ==> Code.abort (STR ''cless_eq_set: ccompare = None'') (λ_. cless_eq_set A B) | Some c ==> if finite A ∧ finite B then ord.lexordp_eq (λx y. lt_of_comp c y x) (csorted_list_of_set A) (csorted_list_of_set B) else Code.abort (STR ''cless_eq_set: infinite set'') (λ_. cless_eq_set A B))"
(is"?fin_fin") proof - note [split] = option.split csorted_list_of_set_split and [simp] =
le_of_comp_set_less_eq
finite_subset[OF subset_UNIV] ccompare_set_def ID_Some
ord.lexord_eq_fusion_def proper_intrvl.Compl_set_less_eq_aux_fusion_def
proper_intrvl.set_less_eq_aux_Compl_fusion_def
unfoldr_rbt_keys_generator
RBT_set_def sorted_RBT_Set_keys member_conv_keys
linorder.set_less_eq_finite_iff[OF ID_ccompare]
linorder.set_less_eq_aux_code[OF ID_ccompare, symmetric]
linorder.Compl_set_less_eq_Compl[OF ID_ccompare]
linorder.infinite_set_less_eq_Complement[OF ID_ccompare]
linorder.infinite_Complement_set_less_eq[OF ID_ccompare]
linorder_proper_interval.set_less_eq_aux_Compl2_conv_set_less_eq_aux_Compl[OF ID_ccompare_interval, symmetric]
linorder_proper_interval.Compl1_set_less_eq_aux_conv_Compl_set_less_eq_aux[OF ID_ccompare_interval, symmetric]
show ?Compl_Compl by simp show ?rbt_rbt
by auto show ?rbt_Compl by(cases "finite (UNIV :: 'b set)") auto show ?Compl_rbt by(cases "finite (UNIV :: 'b set)") auto show ?fin_fin by auto show ?fin_Compl_fin by (cases "finite (UNIV :: 'b set)", auto) show ?Compl_fin_fin by(cases "finite (UNIV :: 'b set)") auto qed
lemma cproper_interval_set_Some_Some_code [code]: fixes rbt1 rbt2 :: "'a :: cproper_interval set_rbt" and A B :: "'a set" shows cproper_interval_set_Some_Complement_Some_rbt: "cproper_interval (Some (Complement (RBT_set rbt1))) (Some (RBT_set rbt2)) ⟷ (case ID CCOMPARE('a) of None ==> Code.abort (STR ''cproper_interval (Complement RBT_set) RBT_set: ccompare = None'') (λ_. cproper_interval (Some (Complement (RBT_set rbt1))) (Some (RBT_set rbt2))) | Some c ==> finite (UNIV :: 'a set) ∧ proper_intrvl.proper_interval_Compl_set_aux_fusion (lt_of_comp c) cproper_interval rbt_keys_generator rbt_keys_generator None (RBT_Set2.init rbt1) (RBT_Set2.init rbt2))"
(is ?Compl_rbt_rbt) and cproper_interval_set_Some_rbt_Some_Complement: "cproper_interval (Some (RBT_set rbt1)) (Some (Complement (RBT_set rbt2))) ⟷ (case ID CCOMPARE('a) of None ==> Code.abort (STR ''cproper_interval RBT_set (Complement RBT_set): ccompare = None'') (λ_. cproper_interval (Some (RBT_set rbt1)) (Some (Complement (RBT_set rbt2)))) | Some c ==> finite (UNIV :: 'a set) ∧ proper_intrvl.proper_interval_set_Compl_aux_fusion (lt_of_comp c) cproper_interval rbt_keys_generator rbt_keys_generator None 0 (RBT_Set2.init rbt1) (RBT_Set2.init rbt2))"
(is ?rbt_Compl_rbt) and [set_base_code]: "cproper_interval (Some (RBT_set rbt1)) (Some (RBT_set rbt2)) ⟷ (case ID CCOMPARE('a) of None ==> Code.abort (STR ''cproper_interval RBT_set RBT_set: ccompare = None'') (λ_. cproper_interval (Some (RBT_set rbt1)) (Some (RBT_set rbt2))) | Some c ==> finite (UNIV :: 'a set) ∧ proper_intrvl.proper_interval_set_aux_fusion (lt_of_comp c) cproper_interval rbt_keys_generator rbt_keys_generator (RBT_Set2.init rbt1) (RBT_Set2.init rbt2))"
(is ?rbt_rbt) and cproper_interval_set_Some_Complement_Some_Complement: "cproper_interval (Some (Complement A)) (Some (Complement B)) ⟷ (case ID CCOMPARE('a) of None ==> Code.abort (STR ''cproper_interval Complement Complement: ccompare = None'') (λ_. cproper_interval (Some (Complement A)) (Some (Complement B))) | Some _ ==> cproper_interval (Some B) (Some A))"
(is ?Compl_Compl) and cproper_interval_set_Some_Complement_Some: "cproper_interval (Some (Complement A)) (Some B) ⟷ (case ID CCOMPARE('a) of None ==> Code.abort (STR ''cproper_interval Complement1: ccompare = None'') (λ_. cproper_interval (Some (Complement A)) (Some B)) | Some c ==> finite (UNIV :: 'a set) ∧ proper_intrvl.proper_interval_Compl_set_aux (lt_of_comp c) cproper_interval None (csorted_list_of_set A) (csorted_list_of_set B))"
(is ?Compl_fin_fin) and cproper_interval_set_Some_Some_Complement: "cproper_interval (Some A) (Some (Complement B)) ⟷ (case ID CCOMPARE('a) of None ==> Code.abort (STR ''cproper_interval Complement2: ccompare = None'') (λ_. cproper_interval (Some A) (Some (Complement B))) | Some c ==> finite (UNIV :: 'a set) ∧ proper_intrvl.proper_interval_set_Compl_aux (lt_of_comp c) cproper_interval None 0 (csorted_list_of_set A) (csorted_list_of_set B))"
(is ?fin_Compl_fin) and [set_base_code]: "cproper_interval (Some A) (Some B) ⟷ (case ID CCOMPARE('a) of None ==> Code.abort (STR ''cproper_interval: ccompare = None'') (λ_. cproper_interval (Some A) (Some B)) | Some c ==> finite (UNIV :: 'a set) ∧ proper_intrvl.proper_interval_set_aux (lt_of_comp c) cproper_interval (csorted_list_of_set A) (csorted_list_of_set B))"
(is ?fin_fin) proof - note [split] = option.split csorted_list_of_set_split and [simp] =
lt_of_comp_of_ords
finite_subset[OF subset_UNIV] ccompare_set_def ID_Some
linorder.set_less_finite_iff[OF ID_ccompare]
RBT_set_def sorted_RBT_Set_keys member_conv_keys
linorder.distinct_entries[OF ID_ccompare]
unfoldr_rbt_keys_generator
proper_intrvl.proper_interval_set_aux_fusion_def
proper_intrvl.proper_interval_set_Compl_aux_fusion_def
proper_intrvl.proper_interval_Compl_set_aux_fusion_def
linorder_proper_interval.proper_interval_set_aux[OF ID_ccompare_interval]
linorder_proper_interval.proper_interval_set_Compl_aux[OF ID_ccompare_interval]
linorder_proper_interval.proper_interval_Compl_set_aux[OF ID_ccompare_interval] and [cong] = conj_cong
show ?Compl_Compl by(clarsimp simp add: Complement_cproper_interval_set_Complement simp del: cproper_interval_set_Some_Some)
show ?rbt_rbt ?rbt_Compl_rbt ?Compl_rbt_rbt by auto show ?fin_fin ?fin_Compl_fin ?Compl_fin_fin by auto qed
context ord begin
fun sorted_list_subset :: "('a ==> 'a ==> bool) ==> 'a list ==> 'a list ==> bool" where "sorted_list_subset eq [] ys = True"
| "sorted_list_subset eq (x # xs) [] = False"
| "sorted_list_subset eq (x # xs) (y # ys) ⟷ (if eq x y then sorted_list_subset eq xs ys else x > y ∧ sorted_list_subset eq (x # xs) ys)"
end
context linorder begin
lemma sorted_list_subset_correct: "[ sorted xs; distinct xs; sorted ys; distinct ys ] ==> sorted_list_subset (=) xs ys ⟷ set xs ⊆ set ys" apply(induct "(=) :: 'a ==> 'a ==> bool" xs ys rule: sorted_list_subset.induct) apply(auto 62) using order_antisym apply auto done
lemma Id_on_code [code]: fixes A :: "'a :: ceq set" and dxs :: "'a set_dlist" and P :: "'a ==> bool" and rbt :: "'b :: ccompare set_rbt" shows [set_base_code]: "Id_on (RBT_set rbt) = (case ID CCOMPARE('b) of None ==> Code.abort (STR ''Id_on RBT_set: ccompare = None'') (λ_. Id_on (RBT_set rbt)) | Some _ ==> RBT_set (RBT_Set2.Id_on rbt))" "Id_on (DList_set dxs) = (case ID CEQ('a) of None ==> Code.abort (STR ''Id_on DList_set: ceq = None'') (λ_. Id_on (DList_set dxs)) | Some _ ==> DList_set (DList_Set.Id_on dxs))" "Id_on (Collect_set P) = (case ID CEQ('a) of None ==> Code.abort (STR ''Id_on Collect_set: ceq = None'') (λ_. Id_on (Collect_set P)) | Some eq ==> Collect_set (λ(x, y). eq x y ∧ P x))" and Id_on_Complement: "Id_on (Complement A) = (case ID CEQ('a) of None ==> Code.abort (STR ''Id_on Complement: ceq = None'') (λ_. Id_on (Complement A)) | Some eq ==> Collect_set (λ(x, y). eq x y ∧ x ∉ A))" and [set_base_code]: "Id_on B = (λx. (x, x)) ` B" by (auto simp add: DList_set_def RBT_set_def DList_Set.member_Id_on RBT_Set2.member_Id_on dest: equal.equal_eq[OF ID_ceq] split: option.split)
lemma Image_code [code, set_base_code]: fixes dxs :: "('a :: ceq × 'b :: ceq) set_dlist" and rbt :: "('c :: ccompare × 'd :: ccompare) set_rbt" shows "RBT_set rbt `` C = (case ID CCOMPARE('c) of None ==> Code.abort (STR ''Image RBT_set: ccompare1 = None'') (λ_. RBT_set rbt `` C) | Some _ ==> case ID CCOMPARE('d) of None ==> Code.abort (STR ''Image RBT_set: ccompare2 = None'') (λ_. RBT_set rbt `` C) | Some _ ==> RBT_Set2.fold (λ(x, y) acc. if x ∈ C then insert y acc else acc) rbt {})"
(is ?RBT_set) "DList_set dxs `` B = (case ID CEQ('a) of None ==> Code.abort (STR ''Image DList_set: ceq1 = None'') (λ_. DList_set dxs `` B) | Some _ ==> case ID CEQ('b) of None ==> Code.abort (STR ''Image DList_set: ceq2 = None'') (λ_. DList_set dxs `` B) | Some _ ==> DList_Set.fold (λ(x, y) acc. if x ∈ B then insert y acc else acc) dxs {})"
(is ?DList_set) "Set_Monad rxs `` A = Set_Monad (fold (λ(x, y) rest. if x ∈ A then y # rest else rest) rxs [])"
(is ?Set_Monad) "X `` Y = snd ` Set.filter (λ(x, y). x ∈ Y) X"
(is ?generic) proof - show ?generic by(auto intro: rev_image_eqI)
have"set (fold (λ(x, y) rest. if x ∈ A then y # rest else rest) rxs []) = set rxs `` A" by(induct rxs rule: rev_induct)(auto split: if_split_asm) thus ?Set_Monad by(auto)
{ fix dxs :: "('a × 'b) list" have"fold (λ(x, y) acc. if x ∈ B then insert y acc else acc) dxs {} = set dxs `` B" by(induct dxs rule: rev_induct)(auto split: if_split_asm) } thus ?DList_set by(clarsimp simp add: DList_set_def Collect_member ceq_prod_def ID_Some DList_Set.fold.rep_eq split: option.split)
{ fix rbt :: "(('c × 'd) × unit) list" have"fold (λ(a, _). case a of (x, y) ==> λacc. if x ∈ C then insert y acc else acc) rbt {} = (fst ` set rbt) `` C" by(induct rbt rule: rev_induct)(auto simp add: split_beta split: if_split_asm) } thus ?RBT_set by(clarsimp simp add: RBT_set_def ccompare_prod_def ID_Some RBT_Set2.fold.rep_eq member_conv_keys RBT_Set2.keys.rep_eq RBT_Impl.fold_def RBT_Impl.keys_def split: option.split) qed
lemma insert_relcomp: "insert (a, b) A O B = A O B ∪ {a} × {c. (b, c) ∈ B}" by auto
lemma trancl_code [code, set_base_code]: "trancl A = (if finite A then ntrancl (card A - 1) A else Code.abort (STR ''trancl: infinite set'') (λ_. trancl A))" by (simp add: finite_trancl_ntranl)
lemma set_relcomp_set: "set xs O set ys = fold (λ(x, y). fold (λ(y', z) A. if y = y' then insert (x, z) A else A) ys) xs {}" proof(induct xs rule: rev_induct) case Nil show ?caseby simp next case (snoc x xs) note [[show_types]]
{ fix a :: 'a and b :: 'c and X :: "('a × 'b) set" have"fold (λ(y', z) A. if b = y' then insert (a, z) A else A) ys X = X ∪ {a} × {c. (b, c) ∈ set ys}" by(induct ys arbitrary: X rule: rev_induct)(auto split: if_split_asm) } thus ?caseusing snoc by(cases x)(simp add: insert_relcomp) qed
lemma If_not: "(if ¬ a then b else c) = (if a then c else b)" by auto
lemma relcomp_code [code, set_base_code]: fixes rbt1 :: "('a :: ccompare × 'b :: ccompare) set_rbt" and rbt2 :: "('b × 'c :: ccompare) set_rbt" and rbt3 :: "('a × 'd :: {ccompare, ceq}) set_rbt" and rbt4 :: "('d × 'a) set_rbt" and rbt5 :: "('b × 'a) set_rbt" and dxs1 :: "('d × 'e :: ceq) set_dlist" and dxs2 :: "('e × 'd) set_dlist" and dxs3 :: "('e × 'f :: ceq) set_dlist" and dxs4 :: "('f × 'g :: ceq) set_dlist" and xs1 :: "('h × 'i :: ceq) list" and xs2 :: "('i × 'j) list" and xs3 :: "('b × 'h) list" and xs4 :: "('h × 'b) list" and xs5 :: "('f × 'h) list" and xs6 :: "('h × 'f) list" shows "RBT_set rbt1 O RBT_set rbt2 = (case ID CCOMPARE('a) of None ==> Code.abort (STR ''relcomp RBT_set RBT_set: ccompare1 = None'') (λ_. RBT_set rbt1 O RBT_set rbt2) | Some _ ==> case ID CCOMPARE('b) of None ==> Code.abort (STR ''relcomp RBT_set RBT_set: ccompare2 = None'') (λ_. RBT_set rbt1 O RBT_set rbt2) | Some c_b ==> case ID CCOMPARE('c) of None ==> Code.abort (STR ''relcomp RBT_set RBT_set: ccompare3 = None'') (λ_. RBT_set rbt1 O RBT_set rbt2) | Some _ ==> RBT_Set2.fold (λ(x, y). RBT_Set2.fold (λ(y', z) A. if c_b y y' ≠ Eq then A else insert (x, z) A) rbt2) rbt1 {})"
(is ?rbt_rbt)
"RBT_set rbt3 O DList_set dxs1 = (case ID CCOMPARE('a) of None ==> Code.abort (STR ''relcomp RBT_set DList_set: ccompare1 = None'') (λ_. RBT_set rbt3 O DList_set dxs1) | Some _ ==> case ID CCOMPARE('d) of None ==> Code.abort (STR ''relcomp RBT_set DList_set: ccompare2 = None'') (λ_. RBT_set rbt3 O DList_set dxs1) | Some _ ==> case ID CEQ('d) of None ==> Code.abort (STR ''relcomp RBT_set DList_set: ceq2 = None'') (λ_. RBT_set rbt3 O DList_set dxs1) | Some eq ==> case ID CEQ('e) of None ==> Code.abort (STR ''relcomp RBT_set DList_set: ceq3 = None'') (λ_. RBT_set rbt3 O DList_set dxs1) | Some _ ==> RBT_Set2.fold (λ(x, y). DList_Set.fold (λ(y', z) A. if eq y y' then insert (x, z) A else A) dxs1) rbt3 {})"
(is ?rbt_dlist)
"DList_set dxs2 O RBT_set rbt4 = (case ID CEQ('e) of None ==> Code.abort (STR ''relcomp DList_set RBT_set: ceq1 = None'') (λ_. DList_set dxs2 O RBT_set rbt4) | Some _ ==> case ID CCOMPARE('d) of None ==> Code.abort (STR ''relcomp DList_set RBT_set: ceq2 = None'') (λ_. DList_set dxs2 O RBT_set rbt4) | Some _ ==> case ID CEQ('d) of None ==> Code.abort (STR ''relcomp DList_set RBT_set: ccompare2 = None'') (λ_. DList_set dxs2 O RBT_set rbt4) | Some eq ==> case ID CCOMPARE('a) of None ==> Code.abort (STR ''relcomp DList_set RBT_set: ccompare3 = None'') (λ_. DList_set dxs2 O RBT_set rbt4) | Some _ ==> DList_Set.fold (λ(x, y). RBT_Set2.fold (λ(y', z) A. if eq y y' then insert (x, z) A else A) rbt4) dxs2 {})"
(is ?dlist_rbt)
"DList_set dxs3 O DList_set dxs4 = (case ID CEQ('e) of None ==> Code.abort (STR ''relcomp DList_set DList_set: ceq1 = None'') (λ_. DList_set dxs3 O DList_set dxs4) | Some _ ==> case ID CEQ('f) of None ==> Code.abort (STR ''relcomp DList_set DList_set: ceq2 = None'') (λ_. DList_set dxs3 O DList_set dxs4) | Some eq ==> case ID CEQ('g) of None ==> Code.abort (STR ''relcomp DList_set DList_set: ceq3 = None'') (λ_. DList_set dxs3 O DList_set dxs4) | Some _ ==> DList_Set.fold (λ(x, y). DList_Set.fold (λ(y', z) A. if eq y y' then insert (x, z) A else A) dxs4) dxs3 {})"
(is ?dlist_dlist)
"Set_Monad xs1 O Set_Monad xs2 = (case ID CEQ('i) of None ==> Code.abort (STR ''relcomp Set_Monad Set_Monad: ceq = None'') (λ_. Set_Monad xs1 O Set_Monad xs2) | Some eq ==> fold (λ(x, y). fold (λ(y', z) A. if eq y y' then insert (x, z) A else A) xs2) xs1 {})"
(is ?monad_monad)
"RBT_set rbt1 O Set_Monad xs3 = (case ID CCOMPARE('a) of None ==> Code.abort (STR ''relcomp RBT_set Set_Monad: ccompare1 = None'') (λ_. RBT_set rbt1 O Set_Monad xs3) | Some _ ==> case ID CCOMPARE('b) of None ==> Code.abort (STR ''relcomp RBT_set Set_Monad: ccompare2 = None'') (λ_. RBT_set rbt1 O Set_Monad xs3) | Some c_b ==> RBT_Set2.fold (λ(x, y). fold (λ(y', z) A. if c_b y y' ≠ Eq then A else insert (x, z) A) xs3) rbt1 {})"
(is ?rbt_monad)
"Set_Monad xs4 O RBT_set rbt5 = (case ID CCOMPARE('a) of None ==> Code.abort (STR ''relcomp Set_Monad RBT_set: ccompare1 = None'') (λ_. Set_Monad xs4 O RBT_set rbt5) | Some _ ==> case ID CCOMPARE('b) of None ==> Code.abort (STR ''relcomp Set_Monad RBT_set: ccompare2 = None'') (λ_. Set_Monad xs4 O RBT_set rbt5) | Some c_b ==> fold (λ(x, y). RBT_Set2.fold (λ(y', z) A. if c_b y y' ≠ Eq then A else insert (x, z) A) rbt5) xs4 {})"
(is ?monad_rbt)
"DList_set dxs3 O Set_Monad xs5 = (case ID CEQ('e) of None ==> Code.abort (STR ''relcomp DList_set Set_Monad: ceq1 = None'') (λ_. DList_set dxs3 O Set_Monad xs5) | Some _ ==> case ID CEQ('f) of None ==> Code.abort (STR ''relcomp DList_set Set_Monad: ceq2 = None'') (λ_. DList_set dxs3 O Set_Monad xs5) | Some eq ==> DList_Set.fold (λ(x, y). fold (λ(y', z) A. if eq y y' then insert (x, z) A else A) xs5) dxs3 {})"
(is ?dlist_monad)
"Set_Monad xs6 O DList_set dxs4 = (case ID CEQ('f) of None ==> Code.abort (STR ''relcomp Set_Monad DList_set: ceq1 = None'') (λ_. Set_Monad xs6 O DList_set dxs4) | Some eq ==> case ID CEQ('g) of None ==> Code.abort (STR ''relcomp Set_Monad DList_set: ceq2 = None'') (λ_. Set_Monad xs6 O DList_set dxs4) | Some _ ==> fold (λ(x, y). DList_Set.fold (λ(y', z) A. if eq y y' then insert (x, z) A else A) dxs4) xs6 {})"
(is ?monad_dlist) proof -
lemma irrefl_on_code [code, set_base_code]: fixes r :: "('a :: {ceq, ccompare} × 'a) set"shows "irrefl_on A r ⟷ (case ID CEQ('a) of Some eq ==> (∀(x, y) ∈ r. x ∈ A ⟶ y ∈ A ⟶¬ eq x y) | None ==> case ID CCOMPARE('a) of None ==> Code.abort (STR ''irrefl_on: ceq = None & ccompare = None'') (λ_. irrefl_on A r) | Some c ==> (∀(x, y) ∈ r. x ∈ A ⟶ y ∈ A ⟶ c x y ≠ Eq))" apply(auto simp add: irrefl_on_distinct comparator.eq[OF ID_ccompare'] split: option.split dest!: ID_ceq[THEN equal.equal_eq]) done
lemma bacc_code [code, set_base_code]: "bacc R 0 = - snd ` R" "bacc R (Suc n) = (let rec = bacc R n in rec ∪ - snd ` (Set.filter (λ(y, x). y ∉rec) R))" by(auto intro: rev_image_eqI simp add: Let_def)
(* TODO: acc could also be computed for infinite universes if r is finite *)
lemma acc_code [code, set_base_code]: fixes A :: "('a :: {finite, card_UNIV} × 'a) set"shows "Wellfounded.acc A = bacc A (of_phantom (card_UNIV :: 'a card_UNIV))" by(simp add: card_UNIV acc_bacc_eq)
lemma sorted_list_of_set_code [code, set_base_code]: fixes dxs :: "'a :: {linorder, ceq} set_dlist" and rbt :: "'b :: {linorder, ccompare} set_rbt" shows "sorted_list_of_set (RBT_set rbt) = (case ID CCOMPARE('b) of None ==> Code.abort (STR ''sorted_list_of_set RBT_set: ccompare = None'') (λ_. sorted_list_of_set (RBT_set rbt)) | Some _ ==> sort (RBT_Set2.keys rbt))"
― ‹We must sort the keys because @{term ccompare}'s ordering need not coincide with @{term linorder}'s.› "sorted_list_of_set (DList_set dxs) = (case ID CEQ('a) of None ==> Code.abort (STR ''sorted_list_of_set DList_set: ceq = None'') (λ_. sorted_list_of_set (DList_set dxs)) | Some _ ==> sort (list_of_dlist dxs))" "sorted_list_of_set (Set_Monad xs) = sort (remdups xs)" by (auto simp add: DList_set_def RBT_set_def sorted_list_of_set_sort_remdups Collect_member distinct_remdups_id distinct_list_of_dlist member_conv_keys split: option.split)
lemma image_filter_set_conv_fold: ‹Option.image_filter f (set xs) =
fold (λx A. case f x of None ==> A | Some y ==> insert y A) xs {}› by (induction xs rule: rev_induct) (simp_all add: Option.image_filter_eq split: option.split)
lemma image_filter_code [code, set_base_code]: fixes dxs :: "'a :: ceq set_dlist" and rbt :: "'b :: ccompare set_rbt" shows "Option.image_filter h (RBT_set rbt) = (case ID CCOMPARE('b) of None ==> Code.abort (STR ''Option.image_filter RBT_set: ccompare = None'') (λ_. Option.image_filter h (RBT_set rbt)) | Some _ ==> RBT_Set2.fold (λx A. case h x of None ==> A | Some y ==> insert y A) rbt {})"
(is ?rbt) "Option.image_filter g (DList_set dxs) = (case ID CEQ('a) of None ==> Code.abort (STR ''Option.image_filter DList_set: ceq = None'') (λ_. Option.image_filter g (DList_set dxs)) | Some _ ==> DList_Set.fold (λx A. case g x of None ==> A | Some y ==> insert y A) dxs {})"
(is ?dlist) "Option.image_filter f (Set_Monad xs) = Set_Monad (List.map_filter f xs)"
(is ?set_monad) proof - show ?dlist ?rbt by (auto split: option.split simp add: RBT_set_def DList_set_def DList_Set.fold.rep_eq Collect_member
image_filter_set_conv_fold RBT_Set2.fold_conv_fold_keys member_conv_keys del: equalityI) show ?set_monad by (auto simp add: Option.image_filter_eq Option.these_eq Option.is_none_def List.map_filter_def) qed
lemma these_code [code, set_base_code]: ‹Option.these A = Option.image_filter (λx. x) A› by (simp add: Option.image_filter_eq)
lemma can_select_code: (*TODO: filter_generator not executable!?*) fixes xs :: "'a :: ceq list" and dxs :: "'a :: ceq set_dlist" and rbt :: "'b :: ccompare set_rbt" shows "Set.can_select R (RBT_set rbt) = (case ID CCOMPARE('b) of None ==> Code.abort (STR ''Set.can_select RBT_set: ccompare = None'') (λ_. Set.can_select R (RBT_set rbt)) | Some _ ==> singleton_list_fusion (filter_generator R rbt_keys_generator) (RBT_Set2.init rbt))"
(is ?rbt) "Set.can_select Q (DList_set dxs) = (case ID CEQ('a) of None ==> Code.abort (STR ''Set.can_select DList_set: ceq = None'') (λ_. Set.can_select Q (DList_set dxs)) | Some _ ==> DList_Set.length (DList_Set.filter Q dxs) = 1)"
(is ?dlist) "Set.can_select P (Set_Monad xs) = (case ID CEQ('a) of None ==> Code.abort (STR ''Set.can_select Set_Monad: ceq = None'') (λ_. Set.can_select P (Set_Monad xs)) | Some eq ==> case filter P xs of Nil ==> False | x # xs ==> list_all (eq x) xs)"
(is ?Set_Monad) proof - show ?Set_Monad apply(auto split: option.split list.split dest!: ID_ceq[THEN equal.equal_eq] dest: filter_eq_ConsD simp add: filter_empty_conv list_all_iff) apply(drule filter_eq_ConsD, fastforce) apply(drule filter_eq_ConsD, clarsimp, blast) done
text‹
@{typ "'a Predicate.pred"} is implemented as a monad,
so we keep the monad when converting to @{typ "'a set"}.
For this case, @{term insert_monad} and @{term union_monad}
avoid the unnecessary dictionary construction. ›
definition insert_monad :: "'a ==> 'a set ==> 'a set" where [simp]: "insert_monad = insert"
definition union_monad :: "'a set ==> 'a set ==> 'a set" where [simp]: "union_monad = (∪)"
lemma insert_monad_code [code, set_base_code]: "insert_monad x (Set_Monad xs) = Set_Monad (x # xs)" by simp
derive (choose) set_impl list
derive (rbt) set_impl String.literal
instantiation option :: (set_impl) set_impl begin definition"SET_IMPL('a option) = Phantom('a option) (of_phantom SET_IMPL('a))" instance .. end
derive (monad) set_impl "fun"
derive (choose) set_impl set
instantiation phantom :: (type, set_impl) set_impl begin definition"SET_IMPL(('a, 'b) phantom) = Phantom (('a, 'b) phantom) (of_phantom SET_IMPL('b))" instance .. end
text‹
We enable automatic implementation selection for sets constructed by @{const set},
although they could be directly converted using @{const Set_Monad} in constant time.
However, then it is more likely that the parameters of binary operators have
different implementations, which can lead to less efficient execution.
However, we test whether automatic selection picks @{const Set_Monad} anyway and
take a short-cut. ›
definition set_aux :: "set_impl ==> 'a list ==> 'a set" where [simp]: "set_aux _ = set"
lemma set_aux_code [code, set_base_code]: defines"conv ≡ foldl (λs (x :: 'a). insert x s)" shows "set_aux set_Monad = Set_Monad" "set_aux set_Choose = (case CCOMPARE('a :: {ccompare, ceq}) of Some _ ==> conv (RBT_set RBT_Set2.empty) | None ==> case CEQ('a) of None ==> Set_Monad | Some _ ==> conv (DList_set DList_Set.empty))" (is"?thesis2") "set_aux impl = conv (set_empty impl)" (is"?thesis1") proof - have"conv {} = set" by(rule ext)(induct_tac x rule: rev_induct, simp_all add: conv_def) thus ?thesis1 ?thesis2 by(simp_all split: option.split) qed simp
text‹
@{term code_post} marks contexts (as hypothesis) in which we use code\_post as a
decision procedure rather than a pretty-printing engine.
The intended use is to enable more rules when proving assumptions of rewrite rules. ›
lemma conj_code_post [code_post]: assumes code_post shows"True & x ⟷ x""False & x ⟷ False" by simp_all
text‹
A flag to switch post-processing of sets on and off.
Use \verb$declare pretty_sets[code_post del]$ to disable pretty printing of sets in value. ›
definition collapse_RBT_set :: "'a set_rbt ==> 'a :: ccompare set ==> 'a set" where"collapse_RBT_set r M = set (RBT_Set2.keys r) ∪ M"
lemma RBT_set_collapse_RBT_set [code_post]: fixes r :: "'a :: ccompare set_rbt" assumes"code_post ==> is_ccompare TYPE('a)"and code_post_set shows"RBT_set r = collapse_RBT_set r {}" using assms by(clarsimp simp add: code_post_def is_ccompare_def RBT_set_def member_conv_keys collapse_RBT_set_def)
lemma collapse_RBT_set_Branch [code_post]: "collapse_RBT_set (Mapping_RBT (Branch c l x v r)) M = collapse_RBT_set (Mapping_RBT l) (insert x (collapse_RBT_set (Mapping_RBT r) M))" unfolding collapse_RBT_set_def by(auto simp add: is_ccompare_def set_keys_Mapping_RBT)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.