diff --git a/src/HOL/Library/FSet.thy b/src/HOL/Library/FSet.thy --- a/src/HOL/Library/FSet.thy +++ b/src/HOL/Library/FSet.thy @@ -1,1951 +1,1951 @@ (* Title: HOL/Library/FSet.thy Author: Ondrej Kuncar, TU Muenchen Author: Cezary Kaliszyk and Christian Urban Author: Andrei Popescu, TU Muenchen Author: Martin Desharnais, MPI-INF Saarbruecken *) section \Type of finite sets defined as a subtype of sets\ theory FSet imports Main Countable begin subsection \Definition of the type\ typedef 'a fset = "{A :: 'a set. finite A}" morphisms fset Abs_fset by auto setup_lifting type_definition_fset subsection \Basic operations and type class instantiations\ (* FIXME transfer and right_total vs. bi_total *) instantiation fset :: (finite) finite begin instance by (standard; transfer; simp) end instantiation fset :: (type) "{bounded_lattice_bot, distrib_lattice, minus}" begin lift_definition bot_fset :: "'a fset" is "{}" parametric empty_transfer by simp lift_definition less_eq_fset :: "'a fset \ 'a fset \ bool" is subset_eq parametric subset_transfer . definition less_fset :: "'a fset \ 'a fset \ bool" where "xs < ys \ xs \ ys \ xs \ (ys::'a fset)" lemma less_fset_transfer[transfer_rule]: includes lifting_syntax assumes [transfer_rule]: "bi_unique A" shows "((pcr_fset A) ===> (pcr_fset A) ===> (=)) (\) (<)" unfolding less_fset_def[abs_def] psubset_eq[abs_def] by transfer_prover lift_definition sup_fset :: "'a fset \ 'a fset \ 'a fset" is union parametric union_transfer by simp lift_definition inf_fset :: "'a fset \ 'a fset \ 'a fset" is inter parametric inter_transfer by simp lift_definition minus_fset :: "'a fset \ 'a fset \ 'a fset" is minus parametric Diff_transfer by simp instance by (standard; transfer; auto)+ end abbreviation fempty :: "'a fset" ("{||}") where "{||} \ bot" abbreviation fsubset_eq :: "'a fset \ 'a fset \ bool" (infix "|\|" 50) where "xs |\| ys \ xs \ ys" abbreviation fsubset :: "'a fset \ 'a fset \ bool" (infix "|\|" 50) where "xs |\| ys \ xs < ys" abbreviation funion :: "'a fset \ 'a fset \ 'a fset" (infixl "|\|" 65) where "xs |\| ys \ sup xs ys" abbreviation finter :: "'a fset \ 'a fset \ 'a fset" (infixl "|\|" 65) where "xs |\| ys \ inf xs ys" abbreviation fminus :: "'a fset \ 'a fset \ 'a fset" (infixl "|-|" 65) where "xs |-| ys \ minus xs ys" instantiation fset :: (equal) equal begin definition "HOL.equal A B \ A |\| B \ B |\| A" instance by intro_classes (auto simp add: equal_fset_def) end instantiation fset :: (type) conditionally_complete_lattice begin context includes lifting_syntax begin lemma right_total_Inf_fset_transfer: assumes [transfer_rule]: "bi_unique A" and [transfer_rule]: "right_total A" shows "(rel_set (rel_set A) ===> rel_set A) (\S. if finite (\S \ Collect (Domainp A)) then \S \ Collect (Domainp A) else {}) (\S. if finite (Inf S) then Inf S else {})" by transfer_prover lemma Inf_fset_transfer: assumes [transfer_rule]: "bi_unique A" and [transfer_rule]: "bi_total A" shows "(rel_set (rel_set A) ===> rel_set A) (\A. if finite (Inf A) then Inf A else {}) (\A. if finite (Inf A) then Inf A else {})" by transfer_prover lift_definition Inf_fset :: "'a fset set \ 'a fset" is "\A. if finite (Inf A) then Inf A else {}" parametric right_total_Inf_fset_transfer Inf_fset_transfer by simp lemma Sup_fset_transfer: assumes [transfer_rule]: "bi_unique A" shows "(rel_set (rel_set A) ===> rel_set A) (\A. if finite (Sup A) then Sup A else {}) (\A. if finite (Sup A) then Sup A else {})" by transfer_prover lift_definition Sup_fset :: "'a fset set \ 'a fset" is "\A. if finite (Sup A) then Sup A else {}" parametric Sup_fset_transfer by simp lemma finite_Sup: "\z. finite z \ (\a. a \ X \ a \ z) \ finite (Sup X)" by (auto intro: finite_subset) lemma transfer_bdd_below[transfer_rule]: "(rel_set (pcr_fset (=)) ===> (=)) bdd_below bdd_below" by auto end instance proof fix x z :: "'a fset" fix X :: "'a fset set" { assume "x \ X" "bdd_below X" then show "Inf X |\| x" by transfer auto next assume "X \ {}" "(\x. x \ X \ z |\| x)" then show "z |\| Inf X" by transfer (clarsimp, blast) next assume "x \ X" "bdd_above X" then obtain z where "x \ X" "(\x. x \ X \ x |\| z)" by (auto simp: bdd_above_def) then show "x |\| Sup X" by transfer (auto intro!: finite_Sup) next assume "X \ {}" "(\x. x \ X \ x |\| z)" then show "Sup X |\| z" by transfer (clarsimp, blast) } qed end instantiation fset :: (finite) complete_lattice begin lift_definition top_fset :: "'a fset" is UNIV parametric right_total_UNIV_transfer UNIV_transfer by simp instance by (standard; transfer; auto) end instantiation fset :: (finite) complete_boolean_algebra begin lift_definition uminus_fset :: "'a fset \ 'a fset" is uminus parametric right_total_Compl_transfer Compl_transfer by simp instance by (standard; transfer) (simp_all add: Inf_Sup Diff_eq) end abbreviation fUNIV :: "'a::finite fset" where "fUNIV \ top" abbreviation fuminus :: "'a::finite fset \ 'a fset" ("|-| _" [81] 80) where "|-| x \ uminus x" declare top_fset.rep_eq[simp] subsection \Other operations\ lift_definition finsert :: "'a \ 'a fset \ 'a fset" is insert parametric Lifting_Set.insert_transfer by simp syntax "_insert_fset" :: "args => 'a fset" ("{|(_)|}") translations "{|x, xs|}" == "CONST finsert x {|xs|}" "{|x|}" == "CONST finsert x {||}" abbreviation fmember :: "'a \ 'a fset \ bool" (infix "|\|" 50) where "x |\| X \ x \ fset X" -abbreviation notin_fset :: "'a \ 'a fset \ bool" (infix "|\|" 50) where +abbreviation not_fmember :: "'a \ 'a fset \ bool" (infix "|\|" 50) where "x |\| X \ x \ fset X" context includes lifting_syntax begin lemma fmember_transfer0[transfer_rule]: assumes [transfer_rule]: "bi_unique A" shows "(A ===> pcr_fset A ===> (=)) (\) (|\|)" by transfer_prover lift_definition ffilter :: "('a \ bool) \ 'a fset \ 'a fset" is Set.filter parametric Lifting_Set.filter_transfer unfolding Set.filter_def by simp lift_definition fPow :: "'a fset \ 'a fset fset" is Pow parametric Pow_transfer by (simp add: finite_subset) lift_definition fcard :: "'a fset \ nat" is card parametric card_transfer . lift_definition fimage :: "('a \ 'b) \ 'a fset \ 'b fset" (infixr "|`|" 90) is image parametric image_transfer by simp lift_definition fthe_elem :: "'a fset \ 'a" is the_elem . lift_definition fbind :: "'a fset \ ('a \ 'b fset) \ 'b fset" is Set.bind parametric bind_transfer by (simp add: Set.bind_def) lift_definition ffUnion :: "'a fset fset \ 'a fset" is Union parametric Union_transfer by simp lift_definition fBall :: "'a fset \ ('a \ bool) \ bool" is Ball parametric Ball_transfer . lift_definition fBex :: "'a fset \ ('a \ bool) \ bool" is Bex parametric Bex_transfer . lift_definition ffold :: "('a \ 'b \ 'b) \ 'b \ 'a fset \ 'b" is Finite_Set.fold . lift_definition fset_of_list :: "'a list \ 'a fset" is set by (rule finite_set) lift_definition sorted_list_of_fset :: "'a::linorder fset \ 'a list" is sorted_list_of_set . subsection \Transferred lemmas from Set.thy\ lemma fset_eqI: "(\x. (x |\| A) = (x |\| B)) \ A = B" by (rule set_eqI[Transfer.transferred]) lemma fset_eq_iff[no_atp]: "(A = B) = (\x. (x |\| A) = (x |\| B))" by (rule set_eq_iff[Transfer.transferred]) lemma fBallI[intro!]: "(\x. x |\| A \ P x) \ fBall A P" by (rule ballI[Transfer.transferred]) lemma fbspec[dest?]: "fBall A P \ x |\| A \ P x" by (rule bspec[Transfer.transferred]) lemma fBallE[elim]: "fBall A P \ (P x \ Q) \ (x |\| A \ Q) \ Q" by (rule ballE[Transfer.transferred]) lemma fBexI[intro]: "P x \ x |\| A \ fBex A P" by (rule bexI[Transfer.transferred]) lemma rev_fBexI[intro?]: "x |\| A \ P x \ fBex A P" by (rule rev_bexI[Transfer.transferred]) lemma fBexCI: "(fBall A (\x. \ P x) \ P a) \ a |\| A \ fBex A P" by (rule bexCI[Transfer.transferred]) lemma fBexE[elim!]: "fBex A P \ (\x. x |\| A \ P x \ Q) \ Q" by (rule bexE[Transfer.transferred]) lemma fBall_triv[simp]: "fBall A (\x. P) = ((\x. x |\| A) \ P)" by (rule ball_triv[Transfer.transferred]) lemma fBex_triv[simp]: "fBex A (\x. P) = ((\x. x |\| A) \ P)" by (rule bex_triv[Transfer.transferred]) lemma fBex_triv_one_point1[simp]: "fBex A (\x. x = a) = (a |\| A)" by (rule bex_triv_one_point1[Transfer.transferred]) lemma fBex_triv_one_point2[simp]: "fBex A ((=) a) = (a |\| A)" by (rule bex_triv_one_point2[Transfer.transferred]) lemma fBex_one_point1[simp]: "fBex A (\x. x = a \ P x) = (a |\| A \ P a)" by (rule bex_one_point1[Transfer.transferred]) lemma fBex_one_point2[simp]: "fBex A (\x. a = x \ P x) = (a |\| A \ P a)" by (rule bex_one_point2[Transfer.transferred]) lemma fBall_one_point1[simp]: "fBall A (\x. x = a \ P x) = (a |\| A \ P a)" by (rule ball_one_point1[Transfer.transferred]) lemma fBall_one_point2[simp]: "fBall A (\x. a = x \ P x) = (a |\| A \ P a)" by (rule ball_one_point2[Transfer.transferred]) lemma fBall_conj_distrib: "fBall A (\x. P x \ Q x) = (fBall A P \ fBall A Q)" by (rule ball_conj_distrib[Transfer.transferred]) lemma fBex_disj_distrib: "fBex A (\x. P x \ Q x) = (fBex A P \ fBex A Q)" by (rule bex_disj_distrib[Transfer.transferred]) lemma fBall_cong[fundef_cong]: "A = B \ (\x. x |\| B \ P x = Q x) \ fBall A P = fBall B Q" by (rule ball_cong[Transfer.transferred]) lemma fBex_cong[fundef_cong]: "A = B \ (\x. x |\| B \ P x = Q x) \ fBex A P = fBex B Q" by (rule bex_cong[Transfer.transferred]) lemma fsubsetI[intro!]: "(\x. x |\| A \ x |\| B) \ A |\| B" by (rule subsetI[Transfer.transferred]) lemma fsubsetD[elim, intro?]: "A |\| B \ c |\| A \ c |\| B" by (rule subsetD[Transfer.transferred]) lemma rev_fsubsetD[no_atp,intro?]: "c |\| A \ A |\| B \ c |\| B" by (rule rev_subsetD[Transfer.transferred]) lemma fsubsetCE[no_atp,elim]: "A |\| B \ (c |\| A \ P) \ (c |\| B \ P) \ P" by (rule subsetCE[Transfer.transferred]) lemma fsubset_eq[no_atp]: "(A |\| B) = fBall A (\x. x |\| B)" by (rule subset_eq[Transfer.transferred]) lemma contra_fsubsetD[no_atp]: "A |\| B \ c |\| B \ c |\| A" by (rule contra_subsetD[Transfer.transferred]) lemma fsubset_refl: "A |\| A" by (rule subset_refl[Transfer.transferred]) lemma fsubset_trans: "A |\| B \ B |\| C \ A |\| C" by (rule subset_trans[Transfer.transferred]) lemma fset_rev_mp: "c |\| A \ A |\| B \ c |\| B" by (rule rev_subsetD[Transfer.transferred]) lemma fset_mp: "A |\| B \ c |\| A \ c |\| B" by (rule subsetD[Transfer.transferred]) lemma fsubset_not_fsubset_eq[code]: "(A |\| B) = (A |\| B \ \ B |\| A)" by (rule subset_not_subset_eq[Transfer.transferred]) lemma eq_fmem_trans: "a = b \ b |\| A \ a |\| A" by (rule eq_mem_trans[Transfer.transferred]) lemma fsubset_antisym[intro!]: "A |\| B \ B |\| A \ A = B" by (rule subset_antisym[Transfer.transferred]) lemma fequalityD1: "A = B \ A |\| B" by (rule equalityD1[Transfer.transferred]) lemma fequalityD2: "A = B \ B |\| A" by (rule equalityD2[Transfer.transferred]) lemma fequalityE: "A = B \ (A |\| B \ B |\| A \ P) \ P" by (rule equalityE[Transfer.transferred]) lemma fequalityCE[elim]: "A = B \ (c |\| A \ c |\| B \ P) \ (c |\| A \ c |\| B \ P) \ P" by (rule equalityCE[Transfer.transferred]) lemma eqfset_imp_iff: "A = B \ (x |\| A) = (x |\| B)" by (rule eqset_imp_iff[Transfer.transferred]) lemma eqfelem_imp_iff: "x = y \ (x |\| A) = (y |\| A)" by (rule eqelem_imp_iff[Transfer.transferred]) lemma fempty_iff[simp]: "(c |\| {||}) = False" by (rule empty_iff[Transfer.transferred]) lemma fempty_fsubsetI[iff]: "{||} |\| x" by (rule empty_subsetI[Transfer.transferred]) lemma equalsffemptyI: "(\y. y |\| A \ False) \ A = {||}" by (rule equals0I[Transfer.transferred]) lemma equalsffemptyD: "A = {||} \ a |\| A" by (rule equals0D[Transfer.transferred]) lemma fBall_fempty[simp]: "fBall {||} P = True" by (rule ball_empty[Transfer.transferred]) lemma fBex_fempty[simp]: "fBex {||} P = False" by (rule bex_empty[Transfer.transferred]) lemma fPow_iff[iff]: "(A |\| fPow B) = (A |\| B)" by (rule Pow_iff[Transfer.transferred]) lemma fPowI: "A |\| B \ A |\| fPow B" by (rule PowI[Transfer.transferred]) lemma fPowD: "A |\| fPow B \ A |\| B" by (rule PowD[Transfer.transferred]) lemma fPow_bottom: "{||} |\| fPow B" by (rule Pow_bottom[Transfer.transferred]) lemma fPow_top: "A |\| fPow A" by (rule Pow_top[Transfer.transferred]) lemma fPow_not_fempty: "fPow A \ {||}" by (rule Pow_not_empty[Transfer.transferred]) lemma finter_iff[simp]: "(c |\| A |\| B) = (c |\| A \ c |\| B)" by (rule Int_iff[Transfer.transferred]) lemma finterI[intro!]: "c |\| A \ c |\| B \ c |\| A |\| B" by (rule IntI[Transfer.transferred]) lemma finterD1: "c |\| A |\| B \ c |\| A" by (rule IntD1[Transfer.transferred]) lemma finterD2: "c |\| A |\| B \ c |\| B" by (rule IntD2[Transfer.transferred]) lemma finterE[elim!]: "c |\| A |\| B \ (c |\| A \ c |\| B \ P) \ P" by (rule IntE[Transfer.transferred]) lemma funion_iff[simp]: "(c |\| A |\| B) = (c |\| A \ c |\| B)" by (rule Un_iff[Transfer.transferred]) lemma funionI1[elim?]: "c |\| A \ c |\| A |\| B" by (rule UnI1[Transfer.transferred]) lemma funionI2[elim?]: "c |\| B \ c |\| A |\| B" by (rule UnI2[Transfer.transferred]) lemma funionCI[intro!]: "(c |\| B \ c |\| A) \ c |\| A |\| B" by (rule UnCI[Transfer.transferred]) lemma funionE[elim!]: "c |\| A |\| B \ (c |\| A \ P) \ (c |\| B \ P) \ P" by (rule UnE[Transfer.transferred]) lemma fminus_iff[simp]: "(c |\| A |-| B) = (c |\| A \ c |\| B)" by (rule Diff_iff[Transfer.transferred]) lemma fminusI[intro!]: "c |\| A \ c |\| B \ c |\| A |-| B" by (rule DiffI[Transfer.transferred]) lemma fminusD1: "c |\| A |-| B \ c |\| A" by (rule DiffD1[Transfer.transferred]) lemma fminusD2: "c |\| A |-| B \ c |\| B \ P" by (rule DiffD2[Transfer.transferred]) lemma fminusE[elim!]: "c |\| A |-| B \ (c |\| A \ c |\| B \ P) \ P" by (rule DiffE[Transfer.transferred]) lemma finsert_iff[simp]: "(a |\| finsert b A) = (a = b \ a |\| A)" by (rule insert_iff[Transfer.transferred]) lemma finsertI1: "a |\| finsert a B" by (rule insertI1[Transfer.transferred]) lemma finsertI2: "a |\| B \ a |\| finsert b B" by (rule insertI2[Transfer.transferred]) lemma finsertE[elim!]: "a |\| finsert b A \ (a = b \ P) \ (a |\| A \ P) \ P" by (rule insertE[Transfer.transferred]) lemma finsertCI[intro!]: "(a |\| B \ a = b) \ a |\| finsert b B" by (rule insertCI[Transfer.transferred]) lemma fsubset_finsert_iff: "(A |\| finsert x B) = (if x |\| A then A |-| {|x|} |\| B else A |\| B)" by (rule subset_insert_iff[Transfer.transferred]) lemma finsert_ident: "x |\| A \ x |\| B \ (finsert x A = finsert x B) = (A = B)" by (rule insert_ident[Transfer.transferred]) lemma fsingletonI[intro!,no_atp]: "a |\| {|a|}" by (rule singletonI[Transfer.transferred]) lemma fsingletonD[dest!,no_atp]: "b |\| {|a|} \ b = a" by (rule singletonD[Transfer.transferred]) lemma fsingleton_iff: "(b |\| {|a|}) = (b = a)" by (rule singleton_iff[Transfer.transferred]) lemma fsingleton_inject[dest!]: "{|a|} = {|b|} \ a = b" by (rule singleton_inject[Transfer.transferred]) lemma fsingleton_finsert_inj_eq[iff,no_atp]: "({|b|} = finsert a A) = (a = b \ A |\| {|b|})" by (rule singleton_insert_inj_eq[Transfer.transferred]) lemma fsingleton_finsert_inj_eq'[iff,no_atp]: "(finsert a A = {|b|}) = (a = b \ A |\| {|b|})" by (rule singleton_insert_inj_eq'[Transfer.transferred]) lemma fsubset_fsingletonD: "A |\| {|x|} \ A = {||} \ A = {|x|}" by (rule subset_singletonD[Transfer.transferred]) lemma fminus_single_finsert: "A |-| {|x|} |\| B \ A |\| finsert x B" by (rule Diff_single_insert[Transfer.transferred]) lemma fdoubleton_eq_iff: "({|a, b|} = {|c, d|}) = (a = c \ b = d \ a = d \ b = c)" by (rule doubleton_eq_iff[Transfer.transferred]) lemma funion_fsingleton_iff: "(A |\| B = {|x|}) = (A = {||} \ B = {|x|} \ A = {|x|} \ B = {||} \ A = {|x|} \ B = {|x|})" by (rule Un_singleton_iff[Transfer.transferred]) lemma fsingleton_funion_iff: "({|x|} = A |\| B) = (A = {||} \ B = {|x|} \ A = {|x|} \ B = {||} \ A = {|x|} \ B = {|x|})" by (rule singleton_Un_iff[Transfer.transferred]) lemma fimage_eqI[simp, intro]: "b = f x \ x |\| A \ b |\| f |`| A" by (rule image_eqI[Transfer.transferred]) lemma fimageI: "x |\| A \ f x |\| f |`| A" by (rule imageI[Transfer.transferred]) lemma rev_fimage_eqI: "x |\| A \ b = f x \ b |\| f |`| A" by (rule rev_image_eqI[Transfer.transferred]) lemma fimageE[elim!]: "b |\| f |`| A \ (\x. b = f x \ x |\| A \ thesis) \ thesis" by (rule imageE[Transfer.transferred]) lemma Compr_fimage_eq: "{x. x |\| f |`| A \ P x} = f ` {x. x |\| A \ P (f x)}" by (rule Compr_image_eq[Transfer.transferred]) lemma fimage_funion: "f |`| (A |\| B) = f |`| A |\| f |`| B" by (rule image_Un[Transfer.transferred]) lemma fimage_iff: "(z |\| f |`| A) = fBex A (\x. z = f x)" by (rule image_iff[Transfer.transferred]) lemma fimage_fsubset_iff[no_atp]: "(f |`| A |\| B) = fBall A (\x. f x |\| B)" by (rule image_subset_iff[Transfer.transferred]) lemma fimage_fsubsetI: "(\x. x |\| A \ f x |\| B) \ f |`| A |\| B" by (rule image_subsetI[Transfer.transferred]) lemma fimage_ident[simp]: "(\x. x) |`| Y = Y" by (rule image_ident[Transfer.transferred]) lemma if_split_fmem1: "((if Q then x else y) |\| b) = ((Q \ x |\| b) \ (\ Q \ y |\| b))" by (rule if_split_mem1[Transfer.transferred]) lemma if_split_fmem2: "(a |\| (if Q then x else y)) = ((Q \ a |\| x) \ (\ Q \ a |\| y))" by (rule if_split_mem2[Transfer.transferred]) lemma pfsubsetI[intro!,no_atp]: "A |\| B \ A \ B \ A |\| B" by (rule psubsetI[Transfer.transferred]) lemma pfsubsetE[elim!,no_atp]: "A |\| B \ (A |\| B \ \ B |\| A \ R) \ R" by (rule psubsetE[Transfer.transferred]) lemma pfsubset_finsert_iff: "(A |\| finsert x B) = (if x |\| B then A |\| B else if x |\| A then A |-| {|x|} |\| B else A |\| B)" by (rule psubset_insert_iff[Transfer.transferred]) lemma pfsubset_eq: "(A |\| B) = (A |\| B \ A \ B)" by (rule psubset_eq[Transfer.transferred]) lemma pfsubset_imp_fsubset: "A |\| B \ A |\| B" by (rule psubset_imp_subset[Transfer.transferred]) lemma pfsubset_trans: "A |\| B \ B |\| C \ A |\| C" by (rule psubset_trans[Transfer.transferred]) lemma pfsubsetD: "A |\| B \ c |\| A \ c |\| B" by (rule psubsetD[Transfer.transferred]) lemma pfsubset_fsubset_trans: "A |\| B \ B |\| C \ A |\| C" by (rule psubset_subset_trans[Transfer.transferred]) lemma fsubset_pfsubset_trans: "A |\| B \ B |\| C \ A |\| C" by (rule subset_psubset_trans[Transfer.transferred]) lemma pfsubset_imp_ex_fmem: "A |\| B \ \b. b |\| B |-| A" by (rule psubset_imp_ex_mem[Transfer.transferred]) lemma fimage_fPow_mono: "f |`| A |\| B \ (|`|) f |`| fPow A |\| fPow B" by (rule image_Pow_mono[Transfer.transferred]) lemma fimage_fPow_surj: "f |`| A = B \ (|`|) f |`| fPow A = fPow B" by (rule image_Pow_surj[Transfer.transferred]) lemma fsubset_finsertI: "B |\| finsert a B" by (rule subset_insertI[Transfer.transferred]) lemma fsubset_finsertI2: "A |\| B \ A |\| finsert b B" by (rule subset_insertI2[Transfer.transferred]) lemma fsubset_finsert: "x |\| A \ (A |\| finsert x B) = (A |\| B)" by (rule subset_insert[Transfer.transferred]) lemma funion_upper1: "A |\| A |\| B" by (rule Un_upper1[Transfer.transferred]) lemma funion_upper2: "B |\| A |\| B" by (rule Un_upper2[Transfer.transferred]) lemma funion_least: "A |\| C \ B |\| C \ A |\| B |\| C" by (rule Un_least[Transfer.transferred]) lemma finter_lower1: "A |\| B |\| A" by (rule Int_lower1[Transfer.transferred]) lemma finter_lower2: "A |\| B |\| B" by (rule Int_lower2[Transfer.transferred]) lemma finter_greatest: "C |\| A \ C |\| B \ C |\| A |\| B" by (rule Int_greatest[Transfer.transferred]) lemma fminus_fsubset: "A |-| B |\| A" by (rule Diff_subset[Transfer.transferred]) lemma fminus_fsubset_conv: "(A |-| B |\| C) = (A |\| B |\| C)" by (rule Diff_subset_conv[Transfer.transferred]) lemma fsubset_fempty[simp]: "(A |\| {||}) = (A = {||})" by (rule subset_empty[Transfer.transferred]) lemma not_pfsubset_fempty[iff]: "\ A |\| {||}" by (rule not_psubset_empty[Transfer.transferred]) lemma finsert_is_funion: "finsert a A = {|a|} |\| A" by (rule insert_is_Un[Transfer.transferred]) lemma finsert_not_fempty[simp]: "finsert a A \ {||}" by (rule insert_not_empty[Transfer.transferred]) lemma fempty_not_finsert: "{||} \ finsert a A" by (rule empty_not_insert[Transfer.transferred]) lemma finsert_absorb: "a |\| A \ finsert a A = A" by (rule insert_absorb[Transfer.transferred]) lemma finsert_absorb2[simp]: "finsert x (finsert x A) = finsert x A" by (rule insert_absorb2[Transfer.transferred]) lemma finsert_commute: "finsert x (finsert y A) = finsert y (finsert x A)" by (rule insert_commute[Transfer.transferred]) lemma finsert_fsubset[simp]: "(finsert x A |\| B) = (x |\| B \ A |\| B)" by (rule insert_subset[Transfer.transferred]) lemma finsert_inter_finsert[simp]: "finsert a A |\| finsert a B = finsert a (A |\| B)" by (rule insert_inter_insert[Transfer.transferred]) lemma finsert_disjoint[simp,no_atp]: "(finsert a A |\| B = {||}) = (a |\| B \ A |\| B = {||})" "({||} = finsert a A |\| B) = (a |\| B \ {||} = A |\| B)" by (rule insert_disjoint[Transfer.transferred])+ lemma disjoint_finsert[simp,no_atp]: "(B |\| finsert a A = {||}) = (a |\| B \ B |\| A = {||})" "({||} = A |\| finsert b B) = (b |\| A \ {||} = A |\| B)" by (rule disjoint_insert[Transfer.transferred])+ lemma fimage_fempty[simp]: "f |`| {||} = {||}" by (rule image_empty[Transfer.transferred]) lemma fimage_finsert[simp]: "f |`| finsert a B = finsert (f a) (f |`| B)" by (rule image_insert[Transfer.transferred]) lemma fimage_constant: "x |\| A \ (\x. c) |`| A = {|c|}" by (rule image_constant[Transfer.transferred]) lemma fimage_constant_conv: "(\x. c) |`| A = (if A = {||} then {||} else {|c|})" by (rule image_constant_conv[Transfer.transferred]) lemma fimage_fimage: "f |`| g |`| A = (\x. f (g x)) |`| A" by (rule image_image[Transfer.transferred]) lemma finsert_fimage[simp]: "x |\| A \ finsert (f x) (f |`| A) = f |`| A" by (rule insert_image[Transfer.transferred]) lemma fimage_is_fempty[iff]: "(f |`| A = {||}) = (A = {||})" by (rule image_is_empty[Transfer.transferred]) lemma fempty_is_fimage[iff]: "({||} = f |`| A) = (A = {||})" by (rule empty_is_image[Transfer.transferred]) lemma fimage_cong: "M = N \ (\x. x |\| N \ f x = g x) \ f |`| M = g |`| N" by (rule image_cong[Transfer.transferred]) lemma fimage_finter_fsubset: "f |`| (A |\| B) |\| f |`| A |\| f |`| B" by (rule image_Int_subset[Transfer.transferred]) lemma fimage_fminus_fsubset: "f |`| A |-| f |`| B |\| f |`| (A |-| B)" by (rule image_diff_subset[Transfer.transferred]) lemma finter_absorb: "A |\| A = A" by (rule Int_absorb[Transfer.transferred]) lemma finter_left_absorb: "A |\| (A |\| B) = A |\| B" by (rule Int_left_absorb[Transfer.transferred]) lemma finter_commute: "A |\| B = B |\| A" by (rule Int_commute[Transfer.transferred]) lemma finter_left_commute: "A |\| (B |\| C) = B |\| (A |\| C)" by (rule Int_left_commute[Transfer.transferred]) lemma finter_assoc: "A |\| B |\| C = A |\| (B |\| C)" by (rule Int_assoc[Transfer.transferred]) lemma finter_ac: "A |\| B |\| C = A |\| (B |\| C)" "A |\| (A |\| B) = A |\| B" "A |\| B = B |\| A" "A |\| (B |\| C) = B |\| (A |\| C)" by (rule Int_ac[Transfer.transferred])+ lemma finter_absorb1: "B |\| A \ A |\| B = B" by (rule Int_absorb1[Transfer.transferred]) lemma finter_absorb2: "A |\| B \ A |\| B = A" by (rule Int_absorb2[Transfer.transferred]) lemma finter_fempty_left: "{||} |\| B = {||}" by (rule Int_empty_left[Transfer.transferred]) lemma finter_fempty_right: "A |\| {||} = {||}" by (rule Int_empty_right[Transfer.transferred]) lemma disjoint_iff_fnot_equal: "(A |\| B = {||}) = fBall A (\x. fBall B ((\) x))" by (rule disjoint_iff_not_equal[Transfer.transferred]) lemma finter_funion_distrib: "A |\| (B |\| C) = A |\| B |\| (A |\| C)" by (rule Int_Un_distrib[Transfer.transferred]) lemma finter_funion_distrib2: "B |\| C |\| A = B |\| A |\| (C |\| A)" by (rule Int_Un_distrib2[Transfer.transferred]) lemma finter_fsubset_iff[no_atp, simp]: "(C |\| A |\| B) = (C |\| A \ C |\| B)" by (rule Int_subset_iff[Transfer.transferred]) lemma funion_absorb: "A |\| A = A" by (rule Un_absorb[Transfer.transferred]) lemma funion_left_absorb: "A |\| (A |\| B) = A |\| B" by (rule Un_left_absorb[Transfer.transferred]) lemma funion_commute: "A |\| B = B |\| A" by (rule Un_commute[Transfer.transferred]) lemma funion_left_commute: "A |\| (B |\| C) = B |\| (A |\| C)" by (rule Un_left_commute[Transfer.transferred]) lemma funion_assoc: "A |\| B |\| C = A |\| (B |\| C)" by (rule Un_assoc[Transfer.transferred]) lemma funion_ac: "A |\| B |\| C = A |\| (B |\| C)" "A |\| (A |\| B) = A |\| B" "A |\| B = B |\| A" "A |\| (B |\| C) = B |\| (A |\| C)" by (rule Un_ac[Transfer.transferred])+ lemma funion_absorb1: "A |\| B \ A |\| B = B" by (rule Un_absorb1[Transfer.transferred]) lemma funion_absorb2: "B |\| A \ A |\| B = A" by (rule Un_absorb2[Transfer.transferred]) lemma funion_fempty_left: "{||} |\| B = B" by (rule Un_empty_left[Transfer.transferred]) lemma funion_fempty_right: "A |\| {||} = A" by (rule Un_empty_right[Transfer.transferred]) lemma funion_finsert_left[simp]: "finsert a B |\| C = finsert a (B |\| C)" by (rule Un_insert_left[Transfer.transferred]) lemma funion_finsert_right[simp]: "A |\| finsert a B = finsert a (A |\| B)" by (rule Un_insert_right[Transfer.transferred]) lemma finter_finsert_left: "finsert a B |\| C = (if a |\| C then finsert a (B |\| C) else B |\| C)" by (rule Int_insert_left[Transfer.transferred]) lemma finter_finsert_left_ifffempty[simp]: "a |\| C \ finsert a B |\| C = B |\| C" by (rule Int_insert_left_if0[Transfer.transferred]) lemma finter_finsert_left_if1[simp]: "a |\| C \ finsert a B |\| C = finsert a (B |\| C)" by (rule Int_insert_left_if1[Transfer.transferred]) lemma finter_finsert_right: "A |\| finsert a B = (if a |\| A then finsert a (A |\| B) else A |\| B)" by (rule Int_insert_right[Transfer.transferred]) lemma finter_finsert_right_ifffempty[simp]: "a |\| A \ A |\| finsert a B = A |\| B" by (rule Int_insert_right_if0[Transfer.transferred]) lemma finter_finsert_right_if1[simp]: "a |\| A \ A |\| finsert a B = finsert a (A |\| B)" by (rule Int_insert_right_if1[Transfer.transferred]) lemma funion_finter_distrib: "A |\| (B |\| C) = A |\| B |\| (A |\| C)" by (rule Un_Int_distrib[Transfer.transferred]) lemma funion_finter_distrib2: "B |\| C |\| A = B |\| A |\| (C |\| A)" by (rule Un_Int_distrib2[Transfer.transferred]) lemma funion_finter_crazy: "A |\| B |\| (B |\| C) |\| (C |\| A) = A |\| B |\| (B |\| C) |\| (C |\| A)" by (rule Un_Int_crazy[Transfer.transferred]) lemma fsubset_funion_eq: "(A |\| B) = (A |\| B = B)" by (rule subset_Un_eq[Transfer.transferred]) lemma funion_fempty[iff]: "(A |\| B = {||}) = (A = {||} \ B = {||})" by (rule Un_empty[Transfer.transferred]) lemma funion_fsubset_iff[no_atp, simp]: "(A |\| B |\| C) = (A |\| C \ B |\| C)" by (rule Un_subset_iff[Transfer.transferred]) lemma funion_fminus_finter: "A |-| B |\| (A |\| B) = A" by (rule Un_Diff_Int[Transfer.transferred]) lemma ffunion_empty[simp]: "ffUnion {||} = {||}" by (rule Union_empty[Transfer.transferred]) lemma ffunion_mono: "A |\| B \ ffUnion A |\| ffUnion B" by (rule Union_mono[Transfer.transferred]) lemma ffunion_insert[simp]: "ffUnion (finsert a B) = a |\| ffUnion B" by (rule Union_insert[Transfer.transferred]) lemma fminus_finter2: "A |\| C |-| (B |\| C) = A |\| C |-| B" by (rule Diff_Int2[Transfer.transferred]) lemma funion_finter_assoc_eq: "(A |\| B |\| C = A |\| (B |\| C)) = (C |\| A)" by (rule Un_Int_assoc_eq[Transfer.transferred]) lemma fBall_funion: "fBall (A |\| B) P = (fBall A P \ fBall B P)" by (rule ball_Un[Transfer.transferred]) lemma fBex_funion: "fBex (A |\| B) P = (fBex A P \ fBex B P)" by (rule bex_Un[Transfer.transferred]) lemma fminus_eq_fempty_iff[simp,no_atp]: "(A |-| B = {||}) = (A |\| B)" by (rule Diff_eq_empty_iff[Transfer.transferred]) lemma fminus_cancel[simp]: "A |-| A = {||}" by (rule Diff_cancel[Transfer.transferred]) lemma fminus_idemp[simp]: "A |-| B |-| B = A |-| B" by (rule Diff_idemp[Transfer.transferred]) lemma fminus_triv: "A |\| B = {||} \ A |-| B = A" by (rule Diff_triv[Transfer.transferred]) lemma fempty_fminus[simp]: "{||} |-| A = {||}" by (rule empty_Diff[Transfer.transferred]) lemma fminus_fempty[simp]: "A |-| {||} = A" by (rule Diff_empty[Transfer.transferred]) lemma fminus_finsertffempty[simp,no_atp]: "x |\| A \ A |-| finsert x B = A |-| B" by (rule Diff_insert0[Transfer.transferred]) lemma fminus_finsert: "A |-| finsert a B = A |-| B |-| {|a|}" by (rule Diff_insert[Transfer.transferred]) lemma fminus_finsert2: "A |-| finsert a B = A |-| {|a|} |-| B" by (rule Diff_insert2[Transfer.transferred]) lemma finsert_fminus_if: "finsert x A |-| B = (if x |\| B then A |-| B else finsert x (A |-| B))" by (rule insert_Diff_if[Transfer.transferred]) lemma finsert_fminus1[simp]: "x |\| B \ finsert x A |-| B = A |-| B" by (rule insert_Diff1[Transfer.transferred]) lemma finsert_fminus_single[simp]: "finsert a (A |-| {|a|}) = finsert a A" by (rule insert_Diff_single[Transfer.transferred]) lemma finsert_fminus: "a |\| A \ finsert a (A |-| {|a|}) = A" by (rule insert_Diff[Transfer.transferred]) lemma fminus_finsert_absorb: "x |\| A \ finsert x A |-| {|x|} = A" by (rule Diff_insert_absorb[Transfer.transferred]) lemma fminus_disjoint[simp]: "A |\| (B |-| A) = {||}" by (rule Diff_disjoint[Transfer.transferred]) lemma fminus_partition: "A |\| B \ A |\| (B |-| A) = B" by (rule Diff_partition[Transfer.transferred]) lemma double_fminus: "A |\| B \ B |\| C \ B |-| (C |-| A) = A" by (rule double_diff[Transfer.transferred]) lemma funion_fminus_cancel[simp]: "A |\| (B |-| A) = A |\| B" by (rule Un_Diff_cancel[Transfer.transferred]) lemma funion_fminus_cancel2[simp]: "B |-| A |\| A = B |\| A" by (rule Un_Diff_cancel2[Transfer.transferred]) lemma fminus_funion: "A |-| (B |\| C) = A |-| B |\| (A |-| C)" by (rule Diff_Un[Transfer.transferred]) lemma fminus_finter: "A |-| (B |\| C) = A |-| B |\| (A |-| C)" by (rule Diff_Int[Transfer.transferred]) lemma funion_fminus: "A |\| B |-| C = A |-| C |\| (B |-| C)" by (rule Un_Diff[Transfer.transferred]) lemma finter_fminus: "A |\| B |-| C = A |\| (B |-| C)" by (rule Int_Diff[Transfer.transferred]) lemma fminus_finter_distrib: "C |\| (A |-| B) = C |\| A |-| (C |\| B)" by (rule Diff_Int_distrib[Transfer.transferred]) lemma fminus_finter_distrib2: "A |-| B |\| C = A |\| C |-| (B |\| C)" by (rule Diff_Int_distrib2[Transfer.transferred]) lemma fUNIV_bool[no_atp]: "fUNIV = {|False, True|}" by (rule UNIV_bool[Transfer.transferred]) lemma fPow_fempty[simp]: "fPow {||} = {|{||}|}" by (rule Pow_empty[Transfer.transferred]) lemma fPow_finsert: "fPow (finsert a A) = fPow A |\| finsert a |`| fPow A" by (rule Pow_insert[Transfer.transferred]) lemma funion_fPow_fsubset: "fPow A |\| fPow B |\| fPow (A |\| B)" by (rule Un_Pow_subset[Transfer.transferred]) lemma fPow_finter_eq[simp]: "fPow (A |\| B) = fPow A |\| fPow B" by (rule Pow_Int_eq[Transfer.transferred]) lemma fset_eq_fsubset: "(A = B) = (A |\| B \ B |\| A)" by (rule set_eq_subset[Transfer.transferred]) lemma fsubset_iff[no_atp]: "(A |\| B) = (\t. t |\| A \ t |\| B)" by (rule subset_iff[Transfer.transferred]) lemma fsubset_iff_pfsubset_eq: "(A |\| B) = (A |\| B \ A = B)" by (rule subset_iff_psubset_eq[Transfer.transferred]) lemma all_not_fin_conv[simp]: "(\x. x |\| A) = (A = {||})" by (rule all_not_in_conv[Transfer.transferred]) lemma ex_fin_conv: "(\x. x |\| A) = (A \ {||})" by (rule ex_in_conv[Transfer.transferred]) lemma fimage_mono: "A |\| B \ f |`| A |\| f |`| B" by (rule image_mono[Transfer.transferred]) lemma fPow_mono: "A |\| B \ fPow A |\| fPow B" by (rule Pow_mono[Transfer.transferred]) lemma finsert_mono: "C |\| D \ finsert a C |\| finsert a D" by (rule insert_mono[Transfer.transferred]) lemma funion_mono: "A |\| C \ B |\| D \ A |\| B |\| C |\| D" by (rule Un_mono[Transfer.transferred]) lemma finter_mono: "A |\| C \ B |\| D \ A |\| B |\| C |\| D" by (rule Int_mono[Transfer.transferred]) lemma fminus_mono: "A |\| C \ D |\| B \ A |-| B |\| C |-| D" by (rule Diff_mono[Transfer.transferred]) lemma fin_mono: "A |\| B \ x |\| A \ x |\| B" by (rule in_mono[Transfer.transferred]) lemma fthe_felem_eq[simp]: "fthe_elem {|x|} = x" by (rule the_elem_eq[Transfer.transferred]) lemma fLeast_mono: "mono f \ fBex S (\x. fBall S ((\) x)) \ (LEAST y. y |\| f |`| S) = f (LEAST x. x |\| S)" by (rule Least_mono[Transfer.transferred]) lemma fbind_fbind: "fbind (fbind A B) C = fbind A (\x. fbind (B x) C)" by (rule Set.bind_bind[Transfer.transferred]) lemma fempty_fbind[simp]: "fbind {||} f = {||}" by (rule empty_bind[Transfer.transferred]) lemma nonfempty_fbind_const: "A \ {||} \ fbind A (\_. B) = B" by (rule nonempty_bind_const[Transfer.transferred]) lemma fbind_const: "fbind A (\_. B) = (if A = {||} then {||} else B)" by (rule bind_const[Transfer.transferred]) lemma ffmember_filter[simp]: "(x |\| ffilter P A) = (x |\| A \ P x)" by (rule member_filter[Transfer.transferred]) lemma fequalityI: "A |\| B \ B |\| A \ A = B" by (rule equalityI[Transfer.transferred]) lemma fset_of_list_simps[simp]: "fset_of_list [] = {||}" "fset_of_list (x21 # x22) = finsert x21 (fset_of_list x22)" by (rule set_simps[Transfer.transferred])+ lemma fset_of_list_append[simp]: "fset_of_list (xs @ ys) = fset_of_list xs |\| fset_of_list ys" by (rule set_append[Transfer.transferred]) lemma fset_of_list_rev[simp]: "fset_of_list (rev xs) = fset_of_list xs" by (rule set_rev[Transfer.transferred]) lemma fset_of_list_map[simp]: "fset_of_list (map f xs) = f |`| fset_of_list xs" by (rule set_map[Transfer.transferred]) subsection \Additional lemmas\ subsubsection \\ffUnion\\ lemma ffUnion_funion_distrib[simp]: "ffUnion (A |\| B) = ffUnion A |\| ffUnion B" by (rule Union_Un_distrib[Transfer.transferred]) subsubsection \\fbind\\ lemma fbind_cong[fundef_cong]: "A = B \ (\x. x |\| B \ f x = g x) \ fbind A f = fbind B g" by transfer force subsubsection \\fsingleton\\ lemma fsingletonE: " b |\| {|a|} \ (b = a \ thesis) \ thesis" by (rule fsingletonD [elim_format]) subsubsection \\femepty\\ lemma fempty_ffilter[simp]: "ffilter (\_. False) A = {||}" by transfer auto (* FIXME, transferred doesn't work here *) lemma femptyE [elim!]: "a |\| {||} \ P" by simp subsubsection \\fset\\ lemma fset_simps[simp]: "fset {||} = {}" "fset (finsert x X) = insert x (fset X)" by (rule bot_fset.rep_eq finsert.rep_eq)+ lemma finite_fset [simp]: shows "finite (fset S)" by transfer simp lemmas fset_cong = fset_inject lemma filter_fset [simp]: shows "fset (ffilter P xs) = Collect P \ fset xs" by transfer auto lemma inter_fset[simp]: "fset (A |\| B) = fset A \ fset B" by (rule inf_fset.rep_eq) lemma union_fset[simp]: "fset (A |\| B) = fset A \ fset B" by (rule sup_fset.rep_eq) lemma minus_fset[simp]: "fset (A |-| B) = fset A - fset B" by (rule minus_fset.rep_eq) subsubsection \\ffilter\\ lemma subset_ffilter: "ffilter P A |\| ffilter Q A = (\ x. x |\| A \ P x \ Q x)" by transfer auto lemma eq_ffilter: "(ffilter P A = ffilter Q A) = (\x. x |\| A \ P x = Q x)" by transfer auto lemma pfsubset_ffilter: "(\x. x |\| A \ P x \ Q x) \ (x |\| A \ \ P x \ Q x) \ ffilter P A |\| ffilter Q A" unfolding less_fset_def by (auto simp add: subset_ffilter eq_ffilter) subsubsection \\fset_of_list\\ lemma fset_of_list_filter[simp]: "fset_of_list (filter P xs) = ffilter P (fset_of_list xs)" by transfer (auto simp: Set.filter_def) lemma fset_of_list_subset[intro]: "set xs \ set ys \ fset_of_list xs |\| fset_of_list ys" by transfer simp lemma fset_of_list_elem: "(x |\| fset_of_list xs) \ (x \ set xs)" by transfer simp subsubsection \\finsert\\ (* FIXME, transferred doesn't work here *) lemma set_finsert: assumes "x |\| A" obtains B where "A = finsert x B" and "x |\| B" using assms by transfer (metis Set.set_insert finite_insert) lemma mk_disjoint_finsert: "a |\| A \ \B. A = finsert a B \ a |\| B" by (rule exI [where x = "A |-| {|a|}"]) blast lemma finsert_eq_iff: assumes "a |\| A" and "b |\| B" shows "(finsert a A = finsert b B) = (if a = b then A = B else \C. A = finsert b C \ b |\| C \ B = finsert a C \ a |\| C)" using assms by transfer (force simp: insert_eq_iff) subsubsection \\fimage\\ lemma subset_fimage_iff: "(B |\| f|`|A) = (\ AA. AA |\| A \ B = f|`|AA)" by transfer (metis mem_Collect_eq rev_finite_subset subset_image_iff) lemma fimage_strict_mono: assumes "inj_on f (fset B)" and "A |\| B" shows "f |`| A |\| f |`| B" \ \TODO: Configure transfer framework to lift @{thm Fun.image_strict_mono}.\ proof (rule pfsubsetI) from \A |\| B\ have "A |\| B" by (rule pfsubset_imp_fsubset) thus "f |`| A |\| f |`| B" by (rule fimage_mono) next from \A |\| B\ have "A |\| B" and "A \ B" by (simp_all add: pfsubset_eq) have "fset A \ fset B" using \A \ B\ by (simp add: fset_cong) hence "f ` fset A \ f ` fset B" using \A |\| B\ by (simp add: inj_on_image_eq_iff[OF \inj_on f (fset B)\] less_eq_fset.rep_eq) hence "fset (f |`| A) \ fset (f |`| B)" by (simp add: fimage.rep_eq) thus "f |`| A \ f |`| B" by (simp add: fset_cong) qed subsubsection \bounded quantification\ lemma bex_simps [simp, no_atp]: "\A P Q. fBex A (\x. P x \ Q) = (fBex A P \ Q)" "\A P Q. fBex A (\x. P \ Q x) = (P \ fBex A Q)" "\P. fBex {||} P = False" "\a B P. fBex (finsert a B) P = (P a \ fBex B P)" "\A P f. fBex (f |`| A) P = fBex A (\x. P (f x))" "\A P. (\ fBex A P) = fBall A (\x. \ P x)" by auto lemma ball_simps [simp, no_atp]: "\A P Q. fBall A (\x. P x \ Q) = (fBall A P \ Q)" "\A P Q. fBall A (\x. P \ Q x) = (P \ fBall A Q)" "\A P Q. fBall A (\x. P \ Q x) = (P \ fBall A Q)" "\A P Q. fBall A (\x. P x \ Q) = (fBex A P \ Q)" "\P. fBall {||} P = True" "\a B P. fBall (finsert a B) P = (P a \ fBall B P)" "\A P f. fBall (f |`| A) P = fBall A (\x. P (f x))" "\A P. (\ fBall A P) = fBex A (\x. \ P x)" by auto lemma atomize_fBall: "(\x. x |\| A ==> P x) == Trueprop (fBall A (\x. P x))" apply (simp only: atomize_all atomize_imp) apply (rule equal_intr_rule) by (transfer, simp)+ lemma fBall_mono[mono]: "P \ Q \ fBall S P \ fBall S Q" by auto lemma fBex_mono[mono]: "P \ Q \ fBex S P \ fBex S Q" by auto end subsubsection \\fcard\\ (* FIXME: improve transferred to handle bounded meta quantification *) lemma fcard_fempty: "fcard {||} = 0" by transfer (rule card.empty) lemma fcard_finsert_disjoint: "x |\| A \ fcard (finsert x A) = Suc (fcard A)" by transfer (rule card_insert_disjoint) lemma fcard_finsert_if: "fcard (finsert x A) = (if x |\| A then fcard A else Suc (fcard A))" by transfer (rule card_insert_if) lemma fcard_0_eq [simp, no_atp]: "fcard A = 0 \ A = {||}" by transfer (rule card_0_eq) lemma fcard_Suc_fminus1: "x |\| A \ Suc (fcard (A |-| {|x|})) = fcard A" by transfer (rule card_Suc_Diff1) lemma fcard_fminus_fsingleton: "x |\| A \ fcard (A |-| {|x|}) = fcard A - 1" by transfer (rule card_Diff_singleton) lemma fcard_fminus_fsingleton_if: "fcard (A |-| {|x|}) = (if x |\| A then fcard A - 1 else fcard A)" by transfer (rule card_Diff_singleton_if) lemma fcard_fminus_finsert[simp]: assumes "a |\| A" and "a |\| B" shows "fcard (A |-| finsert a B) = fcard (A |-| B) - 1" using assms by transfer (rule card_Diff_insert) lemma fcard_finsert: "fcard (finsert x A) = Suc (fcard (A |-| {|x|}))" by transfer (rule card.insert_remove) lemma fcard_finsert_le: "fcard A \ fcard (finsert x A)" by transfer (rule card_insert_le) lemma fcard_mono: "A |\| B \ fcard A \ fcard B" by transfer (rule card_mono) lemma fcard_seteq: "A |\| B \ fcard B \ fcard A \ A = B" by transfer (rule card_seteq) lemma pfsubset_fcard_mono: "A |\| B \ fcard A < fcard B" by transfer (rule psubset_card_mono) lemma fcard_funion_finter: "fcard A + fcard B = fcard (A |\| B) + fcard (A |\| B)" by transfer (rule card_Un_Int) lemma fcard_funion_disjoint: "A |\| B = {||} \ fcard (A |\| B) = fcard A + fcard B" by transfer (rule card_Un_disjoint) lemma fcard_funion_fsubset: "B |\| A \ fcard (A |-| B) = fcard A - fcard B" by transfer (rule card_Diff_subset) lemma diff_fcard_le_fcard_fminus: "fcard A - fcard B \ fcard(A |-| B)" by transfer (rule diff_card_le_card_Diff) lemma fcard_fminus1_less: "x |\| A \ fcard (A |-| {|x|}) < fcard A" by transfer (rule card_Diff1_less) lemma fcard_fminus2_less: "x |\| A \ y |\| A \ fcard (A |-| {|x|} |-| {|y|}) < fcard A" by transfer (rule card_Diff2_less) lemma fcard_fminus1_le: "fcard (A |-| {|x|}) \ fcard A" by transfer (rule card_Diff1_le) lemma fcard_pfsubset: "A |\| B \ fcard A < fcard B \ A < B" by transfer (rule card_psubset) subsubsection \\sorted_list_of_fset\\ lemma sorted_list_of_fset_simps[simp]: "set (sorted_list_of_fset S) = fset S" "fset_of_list (sorted_list_of_fset S) = S" by (transfer, simp)+ subsubsection \\ffold\\ (* FIXME: improve transferred to handle bounded meta quantification *) context comp_fun_commute begin lemma ffold_empty[simp]: "ffold f z {||} = z" by (rule fold_empty[Transfer.transferred]) lemma ffold_finsert [simp]: assumes "x |\| A" shows "ffold f z (finsert x A) = f x (ffold f z A)" using assms by (transfer fixing: f) (rule fold_insert) lemma ffold_fun_left_comm: "f x (ffold f z A) = ffold f (f x z) A" by (transfer fixing: f) (rule fold_fun_left_comm) lemma ffold_finsert2: "x |\| A \ ffold f z (finsert x A) = ffold f (f x z) A" by (transfer fixing: f) (rule fold_insert2) lemma ffold_rec: assumes "x |\| A" shows "ffold f z A = f x (ffold f z (A |-| {|x|}))" using assms by (transfer fixing: f) (rule fold_rec) lemma ffold_finsert_fremove: "ffold f z (finsert x A) = f x (ffold f z (A |-| {|x|}))" by (transfer fixing: f) (rule fold_insert_remove) end lemma ffold_fimage: assumes "inj_on g (fset A)" shows "ffold f z (g |`| A) = ffold (f \ g) z A" using assms by transfer' (rule fold_image) lemma ffold_cong: assumes "comp_fun_commute f" "comp_fun_commute g" "\x. x |\| A \ f x = g x" and "s = t" and "A = B" shows "ffold f s A = ffold g t B" using assms[unfolded comp_fun_commute_def'] by transfer (meson Finite_Set.fold_cong subset_UNIV) context comp_fun_idem begin lemma ffold_finsert_idem: "ffold f z (finsert x A) = f x (ffold f z A)" by (transfer fixing: f) (rule fold_insert_idem) declare ffold_finsert [simp del] ffold_finsert_idem [simp] lemma ffold_finsert_idem2: "ffold f z (finsert x A) = ffold f (f x z) A" by (transfer fixing: f) (rule fold_insert_idem2) end subsubsection \@{term fsubset}\ lemma wfP_pfsubset: "wfP (|\|)" proof (rule wfP_if_convertible_to_nat) show "\x y. x |\| y \ fcard x < fcard y" by (rule pfsubset_fcard_mono) qed subsubsection \Group operations\ locale comm_monoid_fset = comm_monoid begin sublocale set: comm_monoid_set .. lift_definition F :: "('b \ 'a) \ 'b fset \ 'a" is set.F . lemma cong[fundef_cong]: "A = B \ (\x. x |\| B \ g x = h x) \ F g A = F h B" by (rule set.cong[Transfer.transferred]) lemma cong_simp[cong]: "\ A = B; \x. x |\| B =simp=> g x = h x \ \ F g A = F h B" unfolding simp_implies_def by (auto cong: cong) end context comm_monoid_add begin sublocale fsum: comm_monoid_fset plus 0 rewrites "comm_monoid_set.F plus 0 = sum" defines fsum = fsum.F proof - show "comm_monoid_fset (+) 0" by standard show "comm_monoid_set.F (+) 0 = sum" unfolding sum_def .. qed end subsubsection \Semilattice operations\ locale semilattice_fset = semilattice begin sublocale set: semilattice_set .. lift_definition F :: "'a fset \ 'a" is set.F . lemma eq_fold: "F (finsert x A) = ffold f x A" by transfer (rule set.eq_fold) lemma singleton [simp]: "F {|x|} = x" by transfer (rule set.singleton) lemma insert_not_elem: "x |\| A \ A \ {||} \ F (finsert x A) = x \<^bold>* F A" by transfer (rule set.insert_not_elem) lemma in_idem: "x |\| A \ x \<^bold>* F A = F A" by transfer (rule set.in_idem) lemma insert [simp]: "A \ {||} \ F (finsert x A) = x \<^bold>* F A" by transfer (rule set.insert) end locale semilattice_order_fset = binary?: semilattice_order + semilattice_fset begin end context linorder begin sublocale fMin: semilattice_order_fset min less_eq less rewrites "semilattice_set.F min = Min" defines fMin = fMin.F proof - show "semilattice_order_fset min (\) (<)" by standard show "semilattice_set.F min = Min" unfolding Min_def .. qed sublocale fMax: semilattice_order_fset max greater_eq greater rewrites "semilattice_set.F max = Max" defines fMax = fMax.F proof - show "semilattice_order_fset max (\) (>)" by standard show "semilattice_set.F max = Max" unfolding Max_def .. qed end lemma mono_fMax_commute: "mono f \ A \ {||} \ f (fMax A) = fMax (f |`| A)" by transfer (rule mono_Max_commute) lemma mono_fMin_commute: "mono f \ A \ {||} \ f (fMin A) = fMin (f |`| A)" by transfer (rule mono_Min_commute) lemma fMax_in[simp]: "A \ {||} \ fMax A |\| A" by transfer (rule Max_in) lemma fMin_in[simp]: "A \ {||} \ fMin A |\| A" by transfer (rule Min_in) lemma fMax_ge[simp]: "x |\| A \ x \ fMax A" by transfer (rule Max_ge) lemma fMin_le[simp]: "x |\| A \ fMin A \ x" by transfer (rule Min_le) lemma fMax_eqI: "(\y. y |\| A \ y \ x) \ x |\| A \ fMax A = x" by transfer (rule Max_eqI) lemma fMin_eqI: "(\y. y |\| A \ x \ y) \ x |\| A \ fMin A = x" by transfer (rule Min_eqI) lemma fMax_finsert[simp]: "fMax (finsert x A) = (if A = {||} then x else max x (fMax A))" by transfer simp lemma fMin_finsert[simp]: "fMin (finsert x A) = (if A = {||} then x else min x (fMin A))" by transfer simp context linorder begin lemma fset_linorder_max_induct[case_names fempty finsert]: assumes "P {||}" and "\x S. \\y. y |\| S \ y < x; P S\ \ P (finsert x S)" shows "P S" proof - (* FIXME transfer and right_total vs. bi_total *) note Domainp_forall_transfer[transfer_rule] show ?thesis using assms by (transfer fixing: less) (auto intro: finite_linorder_max_induct) qed lemma fset_linorder_min_induct[case_names fempty finsert]: assumes "P {||}" and "\x S. \\y. y |\| S \ y > x; P S\ \ P (finsert x S)" shows "P S" proof - (* FIXME transfer and right_total vs. bi_total *) note Domainp_forall_transfer[transfer_rule] show ?thesis using assms by (transfer fixing: less) (auto intro: finite_linorder_min_induct) qed end subsection \Choice in fsets\ lemma fset_choice: assumes "\x. x |\| A \ (\y. P x y)" shows "\f. \x. x |\| A \ P x (f x)" using assms by transfer metis subsection \Induction and Cases rules for fsets\ lemma fset_exhaust [case_names empty insert, cases type: fset]: assumes fempty_case: "S = {||} \ P" and finsert_case: "\x S'. S = finsert x S' \ P" shows "P" using assms by transfer blast lemma fset_induct [case_names empty insert]: assumes fempty_case: "P {||}" and finsert_case: "\x S. P S \ P (finsert x S)" shows "P S" proof - (* FIXME transfer and right_total vs. bi_total *) note Domainp_forall_transfer[transfer_rule] show ?thesis using assms by transfer (auto intro: finite_induct) qed lemma fset_induct_stronger [case_names empty insert, induct type: fset]: assumes empty_fset_case: "P {||}" and insert_fset_case: "\x S. \x |\| S; P S\ \ P (finsert x S)" shows "P S" proof - (* FIXME transfer and right_total vs. bi_total *) note Domainp_forall_transfer[transfer_rule] show ?thesis using assms by transfer (auto intro: finite_induct) qed lemma fset_card_induct: assumes empty_fset_case: "P {||}" and card_fset_Suc_case: "\S T. Suc (fcard S) = (fcard T) \ P S \ P T" shows "P S" proof (induct S) case empty show "P {||}" by (rule empty_fset_case) next case (insert x S) have h: "P S" by fact have "x |\| S" by fact then have "Suc (fcard S) = fcard (finsert x S)" by transfer auto then show "P (finsert x S)" using h card_fset_Suc_case by simp qed lemma fset_strong_cases: obtains "xs = {||}" | ys x where "x |\| ys" and "xs = finsert x ys" by transfer blast lemma fset_induct2: "P {||} {||} \ (\x xs. x |\| xs \ P (finsert x xs) {||}) \ (\y ys. y |\| ys \ P {||} (finsert y ys)) \ (\x xs y ys. \P xs ys; x |\| xs; y |\| ys\ \ P (finsert x xs) (finsert y ys)) \ P xsa ysa" apply (induct xsa arbitrary: ysa) apply (induct_tac x rule: fset_induct_stronger) apply simp_all apply (induct_tac xa rule: fset_induct_stronger) apply simp_all done subsection \Setup for Lifting/Transfer\ subsubsection \Relator and predicator properties\ lift_definition rel_fset :: "('a \ 'b \ bool) \ 'a fset \ 'b fset \ bool" is rel_set parametric rel_set_transfer . lemma rel_fset_alt_def: "rel_fset R = (\A B. (\x.\y. x|\|A \ y|\|B \ R x y) \ (\y. \x. y|\|B \ x|\|A \ R x y))" apply (rule ext)+ apply transfer' apply (subst rel_set_def[unfolded fun_eq_iff]) by blast lemma finite_rel_set: assumes fin: "finite X" "finite Z" assumes R_S: "rel_set (R OO S) X Z" shows "\Y. finite Y \ rel_set R X Y \ rel_set S Y Z" proof - obtain f where f: "\x\X. R x (f x) \ (\z\Z. S (f x) z)" apply atomize_elim apply (subst bchoice_iff[symmetric]) using R_S[unfolded rel_set_def OO_def] by blast obtain g where g: "\z\Z. S (g z) z \ (\x\X. R x (g z))" apply atomize_elim apply (subst bchoice_iff[symmetric]) using R_S[unfolded rel_set_def OO_def] by blast let ?Y = "f ` X \ g ` Z" have "finite ?Y" by (simp add: fin) moreover have "rel_set R X ?Y" unfolding rel_set_def using f g by clarsimp blast moreover have "rel_set S ?Y Z" unfolding rel_set_def using f g by clarsimp blast ultimately show ?thesis by metis qed subsubsection \Transfer rules for the Transfer package\ text \Unconditional transfer rules\ context includes lifting_syntax begin lemma fempty_transfer [transfer_rule]: "rel_fset A {||} {||}" by (rule empty_transfer[Transfer.transferred]) lemma finsert_transfer [transfer_rule]: "(A ===> rel_fset A ===> rel_fset A) finsert finsert" unfolding rel_fun_def rel_fset_alt_def by blast lemma funion_transfer [transfer_rule]: "(rel_fset A ===> rel_fset A ===> rel_fset A) funion funion" unfolding rel_fun_def rel_fset_alt_def by blast lemma ffUnion_transfer [transfer_rule]: "(rel_fset (rel_fset A) ===> rel_fset A) ffUnion ffUnion" unfolding rel_fun_def rel_fset_alt_def by transfer (simp, fast) lemma fimage_transfer [transfer_rule]: "((A ===> B) ===> rel_fset A ===> rel_fset B) fimage fimage" unfolding rel_fun_def rel_fset_alt_def by simp blast lemma fBall_transfer [transfer_rule]: "(rel_fset A ===> (A ===> (=)) ===> (=)) fBall fBall" unfolding rel_fset_alt_def rel_fun_def by blast lemma fBex_transfer [transfer_rule]: "(rel_fset A ===> (A ===> (=)) ===> (=)) fBex fBex" unfolding rel_fset_alt_def rel_fun_def by blast (* FIXME transfer doesn't work here *) lemma fPow_transfer [transfer_rule]: "(rel_fset A ===> rel_fset (rel_fset A)) fPow fPow" unfolding rel_fun_def using Pow_transfer[unfolded rel_fun_def, rule_format, Transfer.transferred] by blast lemma rel_fset_transfer [transfer_rule]: "((A ===> B ===> (=)) ===> rel_fset A ===> rel_fset B ===> (=)) rel_fset rel_fset" unfolding rel_fun_def using rel_set_transfer[unfolded rel_fun_def,rule_format, Transfer.transferred, where A = A and B = B] by simp lemma bind_transfer [transfer_rule]: "(rel_fset A ===> (A ===> rel_fset B) ===> rel_fset B) fbind fbind" unfolding rel_fun_def using bind_transfer[unfolded rel_fun_def, rule_format, Transfer.transferred] by blast text \Rules requiring bi-unique, bi-total or right-total relations\ lemma fmember_transfer [transfer_rule]: assumes "bi_unique A" shows "(A ===> rel_fset A ===> (=)) (|\|) (|\|)" using assms unfolding rel_fun_def rel_fset_alt_def bi_unique_def by metis lemma finter_transfer [transfer_rule]: assumes "bi_unique A" shows "(rel_fset A ===> rel_fset A ===> rel_fset A) finter finter" using assms unfolding rel_fun_def using inter_transfer[unfolded rel_fun_def, rule_format, Transfer.transferred] by blast lemma fminus_transfer [transfer_rule]: assumes "bi_unique A" shows "(rel_fset A ===> rel_fset A ===> rel_fset A) (|-|) (|-|)" using assms unfolding rel_fun_def using Diff_transfer[unfolded rel_fun_def, rule_format, Transfer.transferred] by blast lemma fsubset_transfer [transfer_rule]: assumes "bi_unique A" shows "(rel_fset A ===> rel_fset A ===> (=)) (|\|) (|\|)" using assms unfolding rel_fun_def using subset_transfer[unfolded rel_fun_def, rule_format, Transfer.transferred] by blast lemma fSup_transfer [transfer_rule]: "bi_unique A \ (rel_set (rel_fset A) ===> rel_fset A) Sup Sup" unfolding rel_fun_def apply clarify apply transfer' using Sup_fset_transfer[unfolded rel_fun_def] by blast (* FIXME: add right_total_fInf_transfer *) lemma fInf_transfer [transfer_rule]: assumes "bi_unique A" and "bi_total A" shows "(rel_set (rel_fset A) ===> rel_fset A) Inf Inf" using assms unfolding rel_fun_def apply clarify apply transfer' using Inf_fset_transfer[unfolded rel_fun_def] by blast lemma ffilter_transfer [transfer_rule]: assumes "bi_unique A" shows "((A ===> (=)) ===> rel_fset A ===> rel_fset A) ffilter ffilter" using assms unfolding rel_fun_def using Lifting_Set.filter_transfer[unfolded rel_fun_def, rule_format, Transfer.transferred] by blast lemma card_transfer [transfer_rule]: "bi_unique A \ (rel_fset A ===> (=)) fcard fcard" unfolding rel_fun_def using card_transfer[unfolded rel_fun_def, rule_format, Transfer.transferred] by blast end lifting_update fset.lifting lifting_forget fset.lifting subsection \BNF setup\ context includes fset.lifting begin lemma rel_fset_alt: "rel_fset R a b \ (\t \ fset a. \u \ fset b. R t u) \ (\t \ fset b. \u \ fset a. R u t)" by transfer (simp add: rel_set_def) lemma fset_to_fset: "finite A \ fset (the_inv fset A) = A" apply (rule f_the_inv_into_f[unfolded inj_on_def]) apply (simp add: fset_inject) apply (rule range_eqI Abs_fset_inverse[symmetric] CollectI)+ . lemma rel_fset_aux: "(\t \ fset a. \u \ fset b. R t u) \ (\u \ fset b. \t \ fset a. R t u) \ ((BNF_Def.Grp {a. fset a \ {(a, b). R a b}} (fimage fst))\\ OO BNF_Def.Grp {a. fset a \ {(a, b). R a b}} (fimage snd)) a b" (is "?L = ?R") proof assume ?L define R' where "R' = the_inv fset (Collect (case_prod R) \ (fset a \ fset b))" (is "_ = the_inv fset ?L'") have "finite ?L'" by (intro finite_Int[OF disjI2] finite_cartesian_product) (transfer, simp)+ hence *: "fset R' = ?L'" unfolding R'_def by (intro fset_to_fset) show ?R unfolding Grp_def relcompp.simps conversep.simps proof (intro CollectI case_prodI exI[of _ a] exI[of _ b] exI[of _ R'] conjI refl) from * show "a = fimage fst R'" using conjunct1[OF \?L\] by (transfer, auto simp add: image_def Int_def split: prod.splits) from * show "b = fimage snd R'" using conjunct2[OF \?L\] by (transfer, auto simp add: image_def Int_def split: prod.splits) qed (auto simp add: *) next assume ?R thus ?L unfolding Grp_def relcompp.simps conversep.simps apply (simp add: subset_eq Ball_def) apply (rule conjI) apply (transfer, clarsimp, metis snd_conv) by (transfer, clarsimp, metis fst_conv) qed bnf "'a fset" map: fimage sets: fset bd: natLeq wits: "{||}" rel: rel_fset apply - apply transfer' apply simp apply transfer' apply force apply transfer apply force apply transfer' apply force apply (rule natLeq_card_order) apply (rule natLeq_cinfinite) apply (rule regularCard_natLeq) apply transfer apply (metis finite_iff_ordLess_natLeq) apply (fastforce simp: rel_fset_alt) apply (simp add: Grp_def relcompp.simps conversep.simps fun_eq_iff rel_fset_alt rel_fset_aux[unfolded OO_Grp_alt]) apply transfer apply simp done lemma rel_fset_fset: "rel_set \ (fset A1) (fset A2) = rel_fset \ A1 A2" by transfer (rule refl) end declare fset.map_comp[simp] fset.map_id[simp] fset.set_map[simp] subsection \Size setup\ context includes fset.lifting begin lift_definition size_fset :: "('a \ nat) \ 'a fset \ nat" is "\f. sum (Suc \ f)" . end instantiation fset :: (type) size begin definition size_fset where size_fset_overloaded_def: "size_fset = FSet.size_fset (\_. 0)" instance .. end lemma size_fset_simps[simp]: "size_fset f X = (\x \ fset X. Suc (f x))" by (rule size_fset_def[THEN meta_eq_to_obj_eq, THEN fun_cong, THEN fun_cong, unfolded map_fun_def comp_def id_apply]) lemma size_fset_overloaded_simps[simp]: "size X = (\x \ fset X. Suc 0)" by (rule size_fset_simps[of "\_. 0", unfolded add_0_left add_0_right, folded size_fset_overloaded_def]) lemma fset_size_o_map: "inj f \ size_fset g \ fimage f = size_fset (g \ f)" apply (subst fun_eq_iff) including fset.lifting by transfer (auto intro: sum.reindex_cong subset_inj_on) setup \ BNF_LFP_Size.register_size_global \<^type_name>\fset\ \<^const_name>\size_fset\ @{thm size_fset_overloaded_def} @{thms size_fset_simps size_fset_overloaded_simps} @{thms fset_size_o_map} \ lifting_update fset.lifting lifting_forget fset.lifting subsection \Advanced relator customization\ text \Set vs. sum relators:\ lemma rel_set_rel_sum[simp]: "rel_set (rel_sum \ \) A1 A2 \ rel_set \ (Inl -` A1) (Inl -` A2) \ rel_set \ (Inr -` A1) (Inr -` A2)" (is "?L \ ?Rl \ ?Rr") proof safe assume L: "?L" show ?Rl unfolding rel_set_def Bex_def vimage_eq proof safe fix l1 assume "Inl l1 \ A1" then obtain a2 where a2: "a2 \ A2" and "rel_sum \ \ (Inl l1) a2" using L unfolding rel_set_def by auto then obtain l2 where "a2 = Inl l2 \ \ l1 l2" by (cases a2, auto) thus "\ l2. Inl l2 \ A2 \ \ l1 l2" using a2 by auto next fix l2 assume "Inl l2 \ A2" then obtain a1 where a1: "a1 \ A1" and "rel_sum \ \ a1 (Inl l2)" using L unfolding rel_set_def by auto then obtain l1 where "a1 = Inl l1 \ \ l1 l2" by (cases a1, auto) thus "\ l1. Inl l1 \ A1 \ \ l1 l2" using a1 by auto qed show ?Rr unfolding rel_set_def Bex_def vimage_eq proof safe fix r1 assume "Inr r1 \ A1" then obtain a2 where a2: "a2 \ A2" and "rel_sum \ \ (Inr r1) a2" using L unfolding rel_set_def by auto then obtain r2 where "a2 = Inr r2 \ \ r1 r2" by (cases a2, auto) thus "\ r2. Inr r2 \ A2 \ \ r1 r2" using a2 by auto next fix r2 assume "Inr r2 \ A2" then obtain a1 where a1: "a1 \ A1" and "rel_sum \ \ a1 (Inr r2)" using L unfolding rel_set_def by auto then obtain r1 where "a1 = Inr r1 \ \ r1 r2" by (cases a1, auto) thus "\ r1. Inr r1 \ A1 \ \ r1 r2" using a1 by auto qed next assume Rl: "?Rl" and Rr: "?Rr" show ?L unfolding rel_set_def Bex_def vimage_eq proof safe fix a1 assume a1: "a1 \ A1" show "\ a2. a2 \ A2 \ rel_sum \ \ a1 a2" proof(cases a1) case (Inl l1) then obtain l2 where "Inl l2 \ A2 \ \ l1 l2" using Rl a1 unfolding rel_set_def by blast thus ?thesis unfolding Inl by auto next case (Inr r1) then obtain r2 where "Inr r2 \ A2 \ \ r1 r2" using Rr a1 unfolding rel_set_def by blast thus ?thesis unfolding Inr by auto qed next fix a2 assume a2: "a2 \ A2" show "\ a1. a1 \ A1 \ rel_sum \ \ a1 a2" proof(cases a2) case (Inl l2) then obtain l1 where "Inl l1 \ A1 \ \ l1 l2" using Rl a2 unfolding rel_set_def by blast thus ?thesis unfolding Inl by auto next case (Inr r2) then obtain r1 where "Inr r1 \ A1 \ \ r1 r2" using Rr a2 unfolding rel_set_def by blast thus ?thesis unfolding Inr by auto qed qed qed subsubsection \Countability\ lemma exists_fset_of_list: "\xs. fset_of_list xs = S" including fset.lifting by transfer (rule finite_list) lemma fset_of_list_surj[simp, intro]: "surj fset_of_list" proof - have "x \ range fset_of_list" for x :: "'a fset" unfolding image_iff using exists_fset_of_list by fastforce thus ?thesis by auto qed instance fset :: (countable) countable proof obtain to_nat :: "'a list \ nat" where "inj to_nat" by (metis ex_inj) moreover have "inj (inv fset_of_list)" using fset_of_list_surj by (rule surj_imp_inj_inv) ultimately have "inj (to_nat \ inv fset_of_list)" by (rule inj_compose) thus "\to_nat::'a fset \ nat. inj to_nat" by auto qed subsection \Quickcheck setup\ text \Setup adapted from sets.\ notation Quickcheck_Exhaustive.orelse (infixr "orelse" 55) context includes term_syntax begin definition [code_unfold]: "valterm_femptyset = Code_Evaluation.valtermify ({||} :: ('a :: typerep) fset)" definition [code_unfold]: "valtermify_finsert x s = Code_Evaluation.valtermify finsert {\} (x :: ('a :: typerep * _)) {\} s" end instantiation fset :: (exhaustive) exhaustive begin fun exhaustive_fset where "exhaustive_fset f i = (if i = 0 then None else (f {||} orelse exhaustive_fset (\A. f A orelse Quickcheck_Exhaustive.exhaustive (\x. if x |\| A then None else f (finsert x A)) (i - 1)) (i - 1)))" instance .. end instantiation fset :: (full_exhaustive) full_exhaustive begin fun full_exhaustive_fset where "full_exhaustive_fset f i = (if i = 0 then None else (f valterm_femptyset orelse full_exhaustive_fset (\A. f A orelse Quickcheck_Exhaustive.full_exhaustive (\x. if fst x |\| fst A then None else f (valtermify_finsert x A)) (i - 1)) (i - 1)))" instance .. end no_notation Quickcheck_Exhaustive.orelse (infixr "orelse" 55) instantiation fset :: (random) random begin context includes state_combinator_syntax begin fun random_aux_fset :: "natural \ natural \ natural \ natural \ ('a fset \ (unit \ term)) \ natural \ natural" where "random_aux_fset 0 j = Quickcheck_Random.collapse (Random.select_weight [(1, Pair valterm_femptyset)])" | "random_aux_fset (Code_Numeral.Suc i) j = Quickcheck_Random.collapse (Random.select_weight [(1, Pair valterm_femptyset), (Code_Numeral.Suc i, Quickcheck_Random.random j \\ (\x. random_aux_fset i j \\ (\s. Pair (valtermify_finsert x s))))])" lemma [code]: "random_aux_fset i j = Quickcheck_Random.collapse (Random.select_weight [(1, Pair valterm_femptyset), (i, Quickcheck_Random.random j \\ (\x. random_aux_fset (i - 1) j \\ (\s. Pair (valtermify_finsert x s))))])" proof (induct i rule: natural.induct) case zero show ?case by (subst select_weight_drop_zero[symmetric]) (simp add: less_natural_def) next case (Suc i) show ?case by (simp only: random_aux_fset.simps Suc_natural_minus_one) qed definition "random_fset i = random_aux_fset i i" instance .. end end end