| author | wenzelm | 
| Sun, 14 Mar 2021 22:55:52 +0100 | |
| changeset 73439 | cb127ce2c092 | 
| parent 70009 | 435fb018e8ee | 
| child 80768 | c7723cc15de8 | 
| permissions | -rw-r--r-- | 
| 47660 | 1 | (* Title: HOL/Quotient_Examples/Lift_FSet.thy | 
| 2 | Author: Brian Huffman, TU Munich | |
| 3 | *) | |
| 4 | ||
| 63167 | 5 | section \<open>Lifting and transfer with a finite set type\<close> | 
| 47660 | 6 | |
| 7 | theory Lift_FSet | |
| 53013 
3fbcfa911863
remove unnecessary dependencies on Library/Quotient_*
 kuncar parents: 
52354diff
changeset | 8 | imports Main | 
| 47660 | 9 | begin | 
| 10 | ||
| 63167 | 11 | subsection \<open>Equivalence relation and quotient type definition\<close> | 
| 47660 | 12 | |
| 13 | definition list_eq :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" | |
| 14 | where [simp]: "list_eq xs ys \<longleftrightarrow> set xs = set ys" | |
| 15 | ||
| 16 | lemma reflp_list_eq: "reflp list_eq" | |
| 17 | unfolding reflp_def by simp | |
| 18 | ||
| 19 | lemma symp_list_eq: "symp list_eq" | |
| 20 | unfolding symp_def by simp | |
| 21 | ||
| 22 | lemma transp_list_eq: "transp list_eq" | |
| 23 | unfolding transp_def by simp | |
| 24 | ||
| 25 | lemma equivp_list_eq: "equivp list_eq" | |
| 26 | by (intro equivpI reflp_list_eq symp_list_eq transp_list_eq) | |
| 27 | ||
| 63343 | 28 | context includes lifting_syntax | 
| 53013 
3fbcfa911863
remove unnecessary dependencies on Library/Quotient_*
 kuncar parents: 
52354diff
changeset | 29 | begin | 
| 
3fbcfa911863
remove unnecessary dependencies on Library/Quotient_*
 kuncar parents: 
52354diff
changeset | 30 | |
| 51376 
8e38ff09864a
simplify Lift_FSet because we have parametricity in Lifting now
 kuncar parents: 
50227diff
changeset | 31 | lemma list_eq_transfer [transfer_rule]: | 
| 
8e38ff09864a
simplify Lift_FSet because we have parametricity in Lifting now
 kuncar parents: 
50227diff
changeset | 32 | assumes [transfer_rule]: "bi_unique A" | 
| 67399 | 33 | shows "(list_all2 A ===> list_all2 A ===> (=)) list_eq list_eq" | 
| 51376 
8e38ff09864a
simplify Lift_FSet because we have parametricity in Lifting now
 kuncar parents: 
50227diff
changeset | 34 | unfolding list_eq_def [abs_def] by transfer_prover | 
| 
8e38ff09864a
simplify Lift_FSet because we have parametricity in Lifting now
 kuncar parents: 
50227diff
changeset | 35 | |
| 
8e38ff09864a
simplify Lift_FSet because we have parametricity in Lifting now
 kuncar parents: 
50227diff
changeset | 36 | quotient_type 'a fset = "'a list" / "list_eq" parametric list_eq_transfer | 
| 47660 | 37 | by (rule equivp_list_eq) | 
| 38 | ||
| 63167 | 39 | subsection \<open>Lifted constant definitions\<close> | 
| 47660 | 40 | |
| 58961 
7c507e664047
dropped redundant transfer rules (now proved and registered by datatype and plugins)
 traytel parents: 
58889diff
changeset | 41 | lift_definition fnil :: "'a fset" ("{||}") is "[]" parametric list.ctr_transfer(1) .
 | 
| 47660 | 42 | |
| 58961 
7c507e664047
dropped redundant transfer rules (now proved and registered by datatype and plugins)
 traytel parents: 
58889diff
changeset | 43 | lift_definition fcons :: "'a \<Rightarrow> 'a fset \<Rightarrow> 'a fset" is Cons parametric list.ctr_transfer(2) | 
| 47660 | 44 | by simp | 
| 45 | ||
| 51376 
8e38ff09864a
simplify Lift_FSet because we have parametricity in Lifting now
 kuncar parents: 
50227diff
changeset | 46 | lift_definition fappend :: "'a fset \<Rightarrow> 'a fset \<Rightarrow> 'a fset" is append parametric append_transfer | 
| 47660 | 47 | by simp | 
| 48 | ||
| 58961 
7c507e664047
dropped redundant transfer rules (now proved and registered by datatype and plugins)
 traytel parents: 
58889diff
changeset | 49 | lift_definition fmap :: "('a \<Rightarrow> 'b) \<Rightarrow> 'a fset \<Rightarrow> 'b fset" is map parametric list.map_transfer
 | 
| 47660 | 50 | by simp | 
| 51 | ||
| 51376 
8e38ff09864a
simplify Lift_FSet because we have parametricity in Lifting now
 kuncar parents: 
50227diff
changeset | 52 | lift_definition ffilter :: "('a \<Rightarrow> bool) \<Rightarrow> 'a fset \<Rightarrow> 'a fset" is filter parametric filter_transfer
 | 
| 47660 | 53 | by simp | 
| 54 | ||
| 58961 
7c507e664047
dropped redundant transfer rules (now proved and registered by datatype and plugins)
 traytel parents: 
58889diff
changeset | 55 | lift_definition fset :: "'a fset \<Rightarrow> 'a set" is set parametric list.set_transfer | 
| 47660 | 56 | by simp | 
| 57 | ||
| 63167 | 58 | text \<open>Constants with nested types (like concat) yield a more | 
| 59 | complicated proof obligation.\<close> | |
| 47660 | 60 | |
| 61 | lemma list_all2_cr_fset: | |
| 62 | "list_all2 cr_fset xs ys \<longleftrightarrow> map abs_fset xs = ys" | |
| 63 | unfolding cr_fset_def | |
| 64 | apply safe | |
| 65 | apply (erule list_all2_induct, simp, simp) | |
| 66 | apply (simp add: list_all2_map2 List.list_all2_refl) | |
| 67 | done | |
| 68 | ||
| 69 | lemma abs_fset_eq_iff: "abs_fset xs = abs_fset ys \<longleftrightarrow> list_eq xs ys" | |
| 70 | using Quotient_rel [OF Quotient_fset] by simp | |
| 71 | ||
| 51376 
8e38ff09864a
simplify Lift_FSet because we have parametricity in Lifting now
 kuncar parents: 
50227diff
changeset | 72 | lift_definition fconcat :: "'a fset fset \<Rightarrow> 'a fset" is concat parametric concat_transfer | 
| 55732 | 73 | proof (simp only: fset.pcr_cr_eq) | 
| 47660 | 74 | fix xss yss :: "'a list list" | 
| 75 | assume "(list_all2 cr_fset OO list_eq OO (list_all2 cr_fset)\<inverse>\<inverse>) xss yss" | |
| 76 | then obtain uss vss where | |
| 77 | "list_all2 cr_fset xss uss" and "list_eq uss vss" and | |
| 78 | "list_all2 cr_fset yss vss" by clarsimp | |
| 79 | hence "list_eq (map abs_fset xss) (map abs_fset yss)" | |
| 80 | unfolding list_all2_cr_fset by simp | |
| 81 | thus "list_eq (concat xss) (concat yss)" | |
| 82 | apply (simp add: set_eq_iff image_def) | |
| 83 | apply safe | |
| 84 | apply (rename_tac xs, drule_tac x="abs_fset xs" in spec) | |
| 85 | apply (drule iffD1, fast, clarsimp simp add: abs_fset_eq_iff, fast) | |
| 86 | apply (rename_tac xs, drule_tac x="abs_fset xs" in spec) | |
| 87 | apply (drule iffD2, fast, clarsimp simp add: abs_fset_eq_iff, fast) | |
| 88 | done | |
| 89 | qed | |
| 90 | ||
| 53013 
3fbcfa911863
remove unnecessary dependencies on Library/Quotient_*
 kuncar parents: 
52354diff
changeset | 91 | lemma member_transfer: | 
| 
3fbcfa911863
remove unnecessary dependencies on Library/Quotient_*
 kuncar parents: 
52354diff
changeset | 92 | assumes [transfer_rule]: "bi_unique A" | 
| 67399 | 93 | shows "(A ===> list_all2 A ===> (=)) (\<lambda>x xs. x \<in> set xs) (\<lambda>x xs. x \<in> set xs)" | 
| 53013 
3fbcfa911863
remove unnecessary dependencies on Library/Quotient_*
 kuncar parents: 
52354diff
changeset | 94 | by transfer_prover | 
| 
3fbcfa911863
remove unnecessary dependencies on Library/Quotient_*
 kuncar parents: 
52354diff
changeset | 95 | |
| 
3fbcfa911863
remove unnecessary dependencies on Library/Quotient_*
 kuncar parents: 
52354diff
changeset | 96 | end | 
| 
3fbcfa911863
remove unnecessary dependencies on Library/Quotient_*
 kuncar parents: 
52354diff
changeset | 97 | |
| 51410 
f0865a641e76
BNF uses fset defined via Lifting/Transfer rather than Quotient
 traytel parents: 
51376diff
changeset | 98 | syntax | 
| 
f0865a641e76
BNF uses fset defined via Lifting/Transfer rather than Quotient
 traytel parents: 
51376diff
changeset | 99 |   "_insert_fset"     :: "args => 'a fset"  ("{|(_)|}")
 | 
| 
f0865a641e76
BNF uses fset defined via Lifting/Transfer rather than Quotient
 traytel parents: 
51376diff
changeset | 100 | |
| 
f0865a641e76
BNF uses fset defined via Lifting/Transfer rather than Quotient
 traytel parents: 
51376diff
changeset | 101 | translations | 
| 
f0865a641e76
BNF uses fset defined via Lifting/Transfer rather than Quotient
 traytel parents: 
51376diff
changeset | 102 |   "{|x, xs|}" == "CONST fcons x {|xs|}"
 | 
| 
f0865a641e76
BNF uses fset defined via Lifting/Transfer rather than Quotient
 traytel parents: 
51376diff
changeset | 103 |   "{|x|}"     == "CONST fcons x {||}"
 | 
| 
f0865a641e76
BNF uses fset defined via Lifting/Transfer rather than Quotient
 traytel parents: 
51376diff
changeset | 104 | |
| 51411 
deb59caefdb3
rename fset_member to fmember and prove parametricity
 kuncar parents: 
51410diff
changeset | 105 | lift_definition fmember :: "'a \<Rightarrow> 'a fset \<Rightarrow> bool" (infix "|\<in>|" 50) is "\<lambda>x xs. x \<in> set xs" | 
| 
deb59caefdb3
rename fset_member to fmember and prove parametricity
 kuncar parents: 
51410diff
changeset | 106 | parametric member_transfer by simp | 
| 51410 
f0865a641e76
BNF uses fset defined via Lifting/Transfer rather than Quotient
 traytel parents: 
51376diff
changeset | 107 | |
| 
f0865a641e76
BNF uses fset defined via Lifting/Transfer rather than Quotient
 traytel parents: 
51376diff
changeset | 108 | abbreviation notin_fset :: "'a \<Rightarrow> 'a fset \<Rightarrow> bool" (infix "|\<notin>|" 50) where | 
| 
f0865a641e76
BNF uses fset defined via Lifting/Transfer rather than Quotient
 traytel parents: 
51376diff
changeset | 109 | "x |\<notin>| S \<equiv> \<not> (x |\<in>| S)" | 
| 
f0865a641e76
BNF uses fset defined via Lifting/Transfer rather than Quotient
 traytel parents: 
51376diff
changeset | 110 | |
| 51411 
deb59caefdb3
rename fset_member to fmember and prove parametricity
 kuncar parents: 
51410diff
changeset | 111 | lemma fmember_fmap[simp]: "a |\<in>| fmap f X = (\<exists>b. b |\<in>| X \<and> a = f b)" | 
| 51410 
f0865a641e76
BNF uses fset defined via Lifting/Transfer rather than Quotient
 traytel parents: 
51376diff
changeset | 112 | by transfer auto | 
| 
f0865a641e76
BNF uses fset defined via Lifting/Transfer rather than Quotient
 traytel parents: 
51376diff
changeset | 113 | |
| 63167 | 114 | text \<open>We can export code:\<close> | 
| 47937 
70375fa2679d
generate abs_eq, use it as a code equation for total quotients; no_abs_code renamed to no_code; added no_code for quotient_type command
 kuncar parents: 
47676diff
changeset | 115 | |
| 70009 
435fb018e8ee
"export_code ... file_prefix ..." is the preferred way to produce output within the logical file-system within the theory context, as well as session exports;
 wenzelm parents: 
67399diff
changeset | 116 | export_code fnil fcons fappend fmap ffilter fset fmember in SML file_prefix fset | 
| 
435fb018e8ee
"export_code ... file_prefix ..." is the preferred way to produce output within the logical file-system within the theory context, as well as session exports;
 wenzelm parents: 
67399diff
changeset | 117 | |
| 47937 
70375fa2679d
generate abs_eq, use it as a code equation for total quotients; no_abs_code renamed to no_code; added no_code for quotient_type command
 kuncar parents: 
47676diff
changeset | 118 | |
| 63167 | 119 | subsection \<open>Using transfer with type \<open>fset\<close>\<close> | 
| 47660 | 120 | |
| 63167 | 121 | text \<open>The correspondence relation \<open>cr_fset\<close> can only relate | 
| 122 | \<open>list\<close> and \<open>fset\<close> types with the same element type. | |
| 123 | To relate nested types like \<open>'a list list\<close> and | |
| 124 | \<open>'a fset fset\<close>, we define a parameterized version of the | |
| 125 | correspondence relation, \<open>pcr_fset\<close>.\<close> | |
| 50227 | 126 | |
| 127 | thm pcr_fset_def | |
| 47660 | 128 | |
| 63167 | 129 | subsection \<open>Transfer examples\<close> | 
| 47660 | 130 | |
| 63167 | 131 | text \<open>The \<open>transfer\<close> method replaces equality on \<open>fset\<close> with the \<open>list_eq\<close> relation on lists, which is | 
| 132 | logically equivalent.\<close> | |
| 47660 | 133 | |
| 134 | lemma "fmap f (fmap g xs) = fmap (f \<circ> g) xs" | |
| 135 | apply transfer | |
| 136 | apply simp | |
| 137 | done | |
| 138 | ||
| 63167 | 139 | text \<open>The \<open>transfer'\<close> variant can replace equality on \<open>fset\<close> with equality on \<open>list\<close>, which is logically stronger | 
| 140 | but sometimes more convenient.\<close> | |
| 47660 | 141 | |
| 142 | lemma "fmap f (fmap g xs) = fmap (f \<circ> g) xs" | |
| 52354 
acb4f932dd24
implement 'transferred' attribute for transfer package, with support for monotonicity of !!/==>
 huffman parents: 
51994diff
changeset | 143 | using map_map [Transfer.transferred] . | 
| 47660 | 144 | |
| 145 | lemma "ffilter p (fmap f xs) = fmap f (ffilter (p \<circ> f) xs)" | |
| 52354 
acb4f932dd24
implement 'transferred' attribute for transfer package, with support for monotonicity of !!/==>
 huffman parents: 
51994diff
changeset | 146 | using filter_map [Transfer.transferred] . | 
| 47660 | 147 | |
| 148 | lemma "ffilter p (ffilter q xs) = ffilter (\<lambda>x. q x \<and> p x) xs" | |
| 52354 
acb4f932dd24
implement 'transferred' attribute for transfer package, with support for monotonicity of !!/==>
 huffman parents: 
51994diff
changeset | 149 | using filter_filter [Transfer.transferred] . | 
| 47660 | 150 | |
| 151 | lemma "fset (fcons x xs) = insert x (fset xs)" | |
| 57816 
d8bbb97689d3
no need for 'set_simps' now that 'datatype_new' generates the desired 'set' property
 blanchet parents: 
55732diff
changeset | 152 | using list.set(2) [Transfer.transferred] . | 
| 47660 | 153 | |
| 154 | lemma "fset (fappend xs ys) = fset xs \<union> fset ys" | |
| 52354 
acb4f932dd24
implement 'transferred' attribute for transfer package, with support for monotonicity of !!/==>
 huffman parents: 
51994diff
changeset | 155 | using set_append [Transfer.transferred] . | 
| 47660 | 156 | |
| 157 | lemma "fset (fconcat xss) = (\<Union>xs\<in>fset xss. fset xs)" | |
| 52354 
acb4f932dd24
implement 'transferred' attribute for transfer package, with support for monotonicity of !!/==>
 huffman parents: 
51994diff
changeset | 158 | using set_concat [Transfer.transferred] . | 
| 47660 | 159 | |
| 160 | lemma "\<forall>x\<in>fset xs. f x = g x \<Longrightarrow> fmap f xs = fmap g xs" | |
| 161 | apply transfer | |
| 162 | apply (simp cong: map_cong del: set_map) | |
| 163 | done | |
| 164 | ||
| 165 | lemma "fnil = fconcat xss \<longleftrightarrow> (\<forall>xs\<in>fset xss. xs = fnil)" | |
| 166 | apply transfer | |
| 167 | apply simp | |
| 168 | done | |
| 169 | ||
| 170 | lemma "fconcat (fmap (\<lambda>x. fcons x fnil) xs) = xs" | |
| 52354 
acb4f932dd24
implement 'transferred' attribute for transfer package, with support for monotonicity of !!/==>
 huffman parents: 
51994diff
changeset | 171 | apply transfer | 
| 47660 | 172 | apply simp | 
| 173 | done | |
| 174 | ||
| 175 | lemma concat_map_concat: "concat (map concat xsss) = concat (concat xsss)" | |
| 176 | by (induct xsss, simp_all) | |
| 177 | ||
| 178 | lemma "fconcat (fmap fconcat xss) = fconcat (fconcat xss)" | |
| 52354 
acb4f932dd24
implement 'transferred' attribute for transfer package, with support for monotonicity of !!/==>
 huffman parents: 
51994diff
changeset | 179 | using concat_map_concat [Transfer.transferred] . | 
| 47660 | 180 | |
| 181 | end |