| 31807 |      1 | 
 | 
|  |      2 | (* Author: Florian Haftmann, TU Muenchen *)
 | 
|  |      3 | 
 | 
|  |      4 | header {* Executable finite sets *}
 | 
|  |      5 | 
 | 
| 31849 |      6 | theory Fset
 | 
| 31807 |      7 | imports List_Set
 | 
|  |      8 | begin
 | 
|  |      9 | 
 | 
| 31846 |     10 | declare mem_def [simp]
 | 
|  |     11 | 
 | 
| 31849 |     12 | 
 | 
| 31807 |     13 | subsection {* Lifting *}
 | 
|  |     14 | 
 | 
|  |     15 | datatype 'a fset = Fset "'a set"
 | 
|  |     16 | 
 | 
|  |     17 | primrec member :: "'a fset \<Rightarrow> 'a set" where
 | 
|  |     18 |   "member (Fset A) = A"
 | 
|  |     19 | 
 | 
|  |     20 | lemma Fset_member [simp]:
 | 
|  |     21 |   "Fset (member A) = A"
 | 
|  |     22 |   by (cases A) simp
 | 
|  |     23 | 
 | 
|  |     24 | definition Set :: "'a list \<Rightarrow> 'a fset" where
 | 
|  |     25 |   "Set xs = Fset (set xs)"
 | 
|  |     26 | 
 | 
|  |     27 | lemma member_Set [simp]:
 | 
|  |     28 |   "member (Set xs) = set xs"
 | 
|  |     29 |   by (simp add: Set_def)
 | 
|  |     30 | 
 | 
|  |     31 | code_datatype Set
 | 
|  |     32 | 
 | 
|  |     33 | 
 | 
|  |     34 | subsection {* Basic operations *}
 | 
|  |     35 | 
 | 
|  |     36 | definition is_empty :: "'a fset \<Rightarrow> bool" where
 | 
| 31846 |     37 |   [simp]: "is_empty A \<longleftrightarrow> List_Set.is_empty (member A)"
 | 
| 31807 |     38 | 
 | 
|  |     39 | lemma is_empty_Set [code]:
 | 
|  |     40 |   "is_empty (Set xs) \<longleftrightarrow> null xs"
 | 
| 31846 |     41 |   by (simp add: is_empty_set)
 | 
| 31807 |     42 | 
 | 
|  |     43 | definition empty :: "'a fset" where
 | 
| 31846 |     44 |   [simp]: "empty = Fset {}"
 | 
| 31807 |     45 | 
 | 
|  |     46 | lemma empty_Set [code]:
 | 
|  |     47 |   "empty = Set []"
 | 
| 31846 |     48 |   by (simp add: Set_def)
 | 
| 31807 |     49 | 
 | 
|  |     50 | definition insert :: "'a \<Rightarrow> 'a fset \<Rightarrow> 'a fset" where
 | 
| 31846 |     51 |   [simp]: "insert x A = Fset (Set.insert x (member A))"
 | 
| 31807 |     52 | 
 | 
|  |     53 | lemma insert_Set [code]:
 | 
|  |     54 |   "insert x (Set xs) = Set (List_Set.insert x xs)"
 | 
| 31846 |     55 |   by (simp add: Set_def insert_set)
 | 
| 31807 |     56 | 
 | 
|  |     57 | definition remove :: "'a \<Rightarrow> 'a fset \<Rightarrow> 'a fset" where
 | 
| 31846 |     58 |   [simp]: "remove x A = Fset (List_Set.remove x (member A))"
 | 
| 31807 |     59 | 
 | 
|  |     60 | lemma remove_Set [code]:
 | 
|  |     61 |   "remove x (Set xs) = Set (remove_all x xs)"
 | 
| 31846 |     62 |   by (simp add: Set_def remove_set)
 | 
| 31807 |     63 | 
 | 
|  |     64 | definition map :: "('a \<Rightarrow> 'b) \<Rightarrow> 'a fset \<Rightarrow> 'b fset" where
 | 
| 31846 |     65 |   [simp]: "map f A = Fset (image f (member A))"
 | 
| 31807 |     66 | 
 | 
|  |     67 | lemma map_Set [code]:
 | 
|  |     68 |   "map f (Set xs) = Set (remdups (List.map f xs))"
 | 
| 31846 |     69 |   by (simp add: Set_def)
 | 
| 31807 |     70 | 
 | 
| 31847 |     71 | definition filter :: "('a \<Rightarrow> bool) \<Rightarrow> 'a fset \<Rightarrow> 'a fset" where
 | 
|  |     72 |   [simp]: "filter P A = Fset (List_Set.project P (member A))"
 | 
| 31807 |     73 | 
 | 
| 31847 |     74 | lemma filter_Set [code]:
 | 
|  |     75 |   "filter P (Set xs) = Set (List.filter P xs)"
 | 
| 31846 |     76 |   by (simp add: Set_def project_set)
 | 
| 31807 |     77 | 
 | 
|  |     78 | definition forall :: "('a \<Rightarrow> bool) \<Rightarrow> 'a fset \<Rightarrow> bool" where
 | 
| 31846 |     79 |   [simp]: "forall P A \<longleftrightarrow> Ball (member A) P"
 | 
| 31807 |     80 | 
 | 
|  |     81 | lemma forall_Set [code]:
 | 
|  |     82 |   "forall P (Set xs) \<longleftrightarrow> list_all P xs"
 | 
| 31846 |     83 |   by (simp add: Set_def ball_set)
 | 
| 31807 |     84 | 
 | 
|  |     85 | definition exists :: "('a \<Rightarrow> bool) \<Rightarrow> 'a fset \<Rightarrow> bool" where
 | 
| 31846 |     86 |   [simp]: "exists P A \<longleftrightarrow> Bex (member A) P"
 | 
| 31807 |     87 | 
 | 
|  |     88 | lemma exists_Set [code]:
 | 
|  |     89 |   "exists P (Set xs) \<longleftrightarrow> list_ex P xs"
 | 
| 31846 |     90 |   by (simp add: Set_def bex_set)
 | 
|  |     91 | 
 | 
| 31849 |     92 | definition card :: "'a fset \<Rightarrow> nat" where
 | 
|  |     93 |   [simp]: "card A = Finite_Set.card (member A)"
 | 
|  |     94 | 
 | 
|  |     95 | lemma card_Set [code]:
 | 
|  |     96 |   "card (Set xs) = length (remdups xs)"
 | 
|  |     97 | proof -
 | 
|  |     98 |   have "Finite_Set.card (set (remdups xs)) = length (remdups xs)"
 | 
|  |     99 |     by (rule distinct_card) simp
 | 
|  |    100 |   then show ?thesis by (simp add: Set_def card_def)
 | 
|  |    101 | qed
 | 
|  |    102 | 
 | 
| 31846 |    103 | 
 | 
|  |    104 | subsection {* Derived operations *}
 | 
|  |    105 | 
 | 
|  |    106 | lemma member_exists [code]:
 | 
|  |    107 |   "member A y \<longleftrightarrow> exists (\<lambda>x. y = x) A"
 | 
|  |    108 |   by simp
 | 
|  |    109 | 
 | 
|  |    110 | definition subfset_eq :: "'a fset \<Rightarrow> 'a fset \<Rightarrow> bool" where
 | 
|  |    111 |   [simp]: "subfset_eq A B \<longleftrightarrow> member A \<subseteq> member B"
 | 
|  |    112 | 
 | 
|  |    113 | lemma subfset_eq_forall [code]:
 | 
|  |    114 |   "subfset_eq A B \<longleftrightarrow> forall (\<lambda>x. member B x) A"
 | 
|  |    115 |   by (simp add: subset_eq)
 | 
|  |    116 | 
 | 
|  |    117 | definition subfset :: "'a fset \<Rightarrow> 'a fset \<Rightarrow> bool" where
 | 
|  |    118 |   [simp]: "subfset A B \<longleftrightarrow> member A \<subset> member B"
 | 
|  |    119 | 
 | 
|  |    120 | lemma subfset_subfset_eq [code]:
 | 
|  |    121 |   "subfset A B \<longleftrightarrow> subfset_eq A B \<and> \<not> subfset_eq B A"
 | 
|  |    122 |   by (simp add: subset)
 | 
|  |    123 | 
 | 
|  |    124 | lemma eq_fset_subfset_eq [code]:
 | 
|  |    125 |   "eq_class.eq A B \<longleftrightarrow> subfset_eq A B \<and> subfset_eq B A"
 | 
|  |    126 |   by (cases A, cases B) (simp add: eq set_eq)
 | 
|  |    127 | 
 | 
|  |    128 | definition inter :: "'a fset \<Rightarrow> 'a fset \<Rightarrow> 'a fset" where
 | 
| 31847 |    129 |   [simp]: "inter A B = Fset (project (member A) (member B))"
 | 
| 31846 |    130 | 
 | 
|  |    131 | lemma inter_project [code]:
 | 
| 31847 |    132 |   "inter A B = filter (member A) B"
 | 
| 31846 |    133 |   by (simp add: inter)
 | 
| 31807 |    134 | 
 | 
|  |    135 | 
 | 
|  |    136 | subsection {* Functorial operations *}
 | 
|  |    137 | 
 | 
|  |    138 | definition union :: "'a fset \<Rightarrow> 'a fset \<Rightarrow> 'a fset" where
 | 
| 31846 |    139 |   [simp]: "union A B = Fset (member A \<union> member B)"
 | 
| 31807 |    140 | 
 | 
|  |    141 | lemma union_insert [code]:
 | 
|  |    142 |   "union (Set xs) A = foldl (\<lambda>A x. insert x A) A xs"
 | 
|  |    143 | proof -
 | 
|  |    144 |   have "foldl (\<lambda>A x. Set.insert x A) (member A) xs =
 | 
|  |    145 |     member (foldl (\<lambda>A x. Fset (Set.insert x (member A))) A xs)"
 | 
|  |    146 |     by (rule foldl_apply_inv) simp
 | 
| 31846 |    147 |   then show ?thesis by (simp add: union_set)
 | 
| 31807 |    148 | qed
 | 
|  |    149 | 
 | 
|  |    150 | definition subtract :: "'a fset \<Rightarrow> 'a fset \<Rightarrow> 'a fset" where
 | 
| 31846 |    151 |   [simp]: "subtract A B = Fset (member B - member A)"
 | 
| 31807 |    152 | 
 | 
|  |    153 | lemma subtract_remove [code]:
 | 
|  |    154 |   "subtract (Set xs) A = foldl (\<lambda>A x. remove x A) A xs"
 | 
|  |    155 | proof -
 | 
|  |    156 |   have "foldl (\<lambda>A x. List_Set.remove x A) (member A) xs =
 | 
|  |    157 |     member (foldl (\<lambda>A x. Fset (List_Set.remove x (member A))) A xs)"
 | 
|  |    158 |     by (rule foldl_apply_inv) simp
 | 
| 31846 |    159 |   then show ?thesis by (simp add: minus_set)
 | 
| 31807 |    160 | qed
 | 
|  |    161 | 
 | 
| 31846 |    162 | definition Inter :: "'a fset fset \<Rightarrow> 'a fset" where
 | 
| 32139 |    163 |   [simp]: "Inter A = Fset (Complete_Lattice.Inter (member ` member A))"
 | 
| 31807 |    164 | 
 | 
| 31846 |    165 | lemma Inter_inter [code]:
 | 
|  |    166 |   "Inter (Set (A # As)) = foldl inter A As"
 | 
|  |    167 | proof -
 | 
|  |    168 |   note Inter_image_eq [simp del] set_map [simp del] set.simps [simp del]
 | 
|  |    169 |   have "foldl (op \<inter>) (member A) (List.map member As) = 
 | 
|  |    170 |     member (foldl (\<lambda>B A. Fset (member B \<inter> A)) A (List.map member As))"
 | 
|  |    171 |     by (rule foldl_apply_inv) simp
 | 
|  |    172 |   then show ?thesis
 | 
|  |    173 |     by (simp add: Inter_set image_set inter_def_raw inter foldl_map)
 | 
|  |    174 | qed
 | 
| 31807 |    175 | 
 | 
| 31846 |    176 | definition Union :: "'a fset fset \<Rightarrow> 'a fset" where
 | 
| 32139 |    177 |   [simp]: "Union A = Fset (Complete_Lattice.Union (member ` member A))"
 | 
| 31807 |    178 | 
 | 
| 31846 |    179 | lemma Union_union [code]:
 | 
|  |    180 |   "Union (Set As) = foldl union empty As"
 | 
|  |    181 | proof -
 | 
|  |    182 |   note Union_image_eq [simp del] set_map [simp del]
 | 
|  |    183 |   have "foldl (op \<union>) (member empty) (List.map member As) = 
 | 
|  |    184 |     member (foldl (\<lambda>B A. Fset (member B \<union> A)) empty (List.map member As))"
 | 
|  |    185 |     by (rule foldl_apply_inv) simp
 | 
|  |    186 |   then show ?thesis
 | 
|  |    187 |     by (simp add: Union_set image_set union_def_raw foldl_map)
 | 
|  |    188 | qed
 | 
| 31807 |    189 | 
 | 
|  |    190 | 
 | 
|  |    191 | subsection {* Misc operations *}
 | 
|  |    192 | 
 | 
|  |    193 | lemma size_fset [code]:
 | 
|  |    194 |   "fset_size f A = 0"
 | 
|  |    195 |   "size A = 0"
 | 
|  |    196 |   by (cases A, simp) (cases A, simp)
 | 
|  |    197 | 
 | 
|  |    198 | lemma fset_case_code [code]:
 | 
|  |    199 |   "fset_case f A = f (member A)"
 | 
|  |    200 |   by (cases A) simp
 | 
|  |    201 | 
 | 
|  |    202 | lemma fset_rec_code [code]:
 | 
|  |    203 |   "fset_rec f A = f (member A)"
 | 
|  |    204 |   by (cases A) simp
 | 
|  |    205 | 
 | 
| 31846 |    206 | 
 | 
|  |    207 | subsection {* Simplified simprules *}
 | 
|  |    208 | 
 | 
|  |    209 | lemma is_empty_simp [simp]:
 | 
|  |    210 |   "is_empty A \<longleftrightarrow> member A = {}"
 | 
|  |    211 |   by (simp add: List_Set.is_empty_def)
 | 
|  |    212 | declare is_empty_def [simp del]
 | 
|  |    213 | 
 | 
|  |    214 | lemma remove_simp [simp]:
 | 
|  |    215 |   "remove x A = Fset (member A - {x})"
 | 
|  |    216 |   by (simp add: List_Set.remove_def)
 | 
|  |    217 | declare remove_def [simp del]
 | 
|  |    218 | 
 | 
| 31847 |    219 | lemma filter_simp [simp]:
 | 
|  |    220 |   "filter P A = Fset {x \<in> member A. P x}"
 | 
| 31846 |    221 |   by (simp add: List_Set.project_def)
 | 
| 31847 |    222 | declare filter_def [simp del]
 | 
| 31846 |    223 | 
 | 
|  |    224 | lemma inter_simp [simp]:
 | 
|  |    225 |   "inter A B = Fset (member A \<inter> member B)"
 | 
|  |    226 |   by (simp add: inter)
 | 
|  |    227 | declare inter_def [simp del]
 | 
|  |    228 | 
 | 
|  |    229 | declare mem_def [simp del]
 | 
|  |    230 | 
 | 
| 31849 |    231 | 
 | 
|  |    232 | hide (open) const is_empty empty insert remove map filter forall exists card
 | 
|  |    233 |   subfset_eq subfset inter union subtract Inter Union
 | 
|  |    234 | 
 | 
| 31807 |    235 | end
 |