6 *) |
6 *) |
7 theory FSet |
7 theory FSet |
8 imports Quotient Quotient_List List |
8 imports Quotient Quotient_List List |
9 begin |
9 begin |
10 |
10 |
|
11 text {* Definiton of List relation and the quotient type *} |
|
12 |
11 fun |
13 fun |
12 list_eq :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" (infix "\<approx>" 50) |
14 list_eq :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" (infix "\<approx>" 50) |
13 where |
15 where |
14 "list_eq xs ys = (\<forall>x. x \<in> set xs \<longleftrightarrow> x \<in> set ys)" |
16 "list_eq xs ys = (\<forall>x. x \<in> set xs \<longleftrightarrow> x \<in> set ys)" |
15 |
17 |
16 lemma list_eq_equivp: |
18 lemma list_eq_equivp: |
17 shows "equivp list_eq" |
19 shows "equivp list_eq" |
18 unfolding equivp_reflp_symp_transp |
20 unfolding equivp_reflp_symp_transp |
19 unfolding reflp_def symp_def transp_def |
21 unfolding reflp_def symp_def transp_def |
20 by auto |
22 by auto |
21 |
23 |
|
24 quotient_type |
|
25 'a fset = "'a list" / "list_eq" |
|
26 by (rule list_eq_equivp) |
|
27 |
|
28 text {* Raw definitions *} |
|
29 |
22 definition |
30 definition |
23 memb :: "'a \<Rightarrow> 'a list \<Rightarrow> bool" |
31 memb :: "'a \<Rightarrow> 'a list \<Rightarrow> bool" |
24 where |
32 where |
25 "memb x xs \<equiv> x \<in> set xs" |
33 "memb x xs \<equiv> x \<in> set xs" |
26 |
34 |
27 definition |
35 definition |
28 sub_list :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" |
36 sub_list :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" |
29 where |
37 where |
30 "sub_list xs ys \<equiv> (\<forall>x. x \<in> set xs \<longrightarrow> x \<in> set ys)" |
38 "sub_list xs ys \<equiv> (\<forall>x. x \<in> set xs \<longrightarrow> x \<in> set ys)" |
31 |
39 |
32 quotient_type |
40 fun |
33 'a fset = "'a list" / "list_eq" |
41 fcard_raw :: "'a list \<Rightarrow> nat" |
34 by (rule list_eq_equivp) |
42 where |
35 |
43 fcard_raw_nil: "fcard_raw [] = 0" |
36 lemma sub_list_rsp1: "\<lbrakk>xs \<approx> ys\<rbrakk> \<Longrightarrow> sub_list xs zs = sub_list ys zs" |
44 | fcard_raw_cons: "fcard_raw (x # xs) = (if memb x xs then fcard_raw xs else Suc (fcard_raw xs))" |
37 by (simp add: sub_list_def) |
45 |
38 |
46 primrec |
39 lemma sub_list_rsp2: "\<lbrakk>xs \<approx> ys\<rbrakk> \<Longrightarrow> sub_list zs xs = sub_list zs ys" |
47 finter_raw :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" |
40 by (simp add: sub_list_def) |
48 where |
41 |
49 "finter_raw [] l = []" |
42 lemma [quot_respect]: |
50 | "finter_raw (h # t) l = |
43 shows "(op \<approx> ===> op \<approx> ===> op =) sub_list sub_list" |
51 (if memb h l then h # (finter_raw t l) else finter_raw t l)" |
44 by (auto simp only: fun_rel_def sub_list_rsp1 sub_list_rsp2) |
52 |
|
53 fun |
|
54 delete_raw :: "'a list \<Rightarrow> 'a \<Rightarrow> 'a list" |
|
55 where |
|
56 "delete_raw [] x = []" |
|
57 | "delete_raw (a # A) x = (if (a = x) then delete_raw A x else a # (delete_raw A x))" |
|
58 |
|
59 definition |
|
60 rsp_fold |
|
61 where |
|
62 "rsp_fold f = (\<forall>u v w. (f u (f v w) = f v (f u w)))" |
|
63 |
|
64 primrec |
|
65 ffold_raw :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a list \<Rightarrow> 'b" |
|
66 where |
|
67 "ffold_raw f z [] = z" |
|
68 | "ffold_raw f z (a # A) = |
|
69 (if (rsp_fold f) then |
|
70 if memb a A then ffold_raw f z A |
|
71 else f a (ffold_raw f z A) |
|
72 else z)" |
|
73 |
|
74 text {* Respectfullness *} |
45 |
75 |
46 lemma [quot_respect]: |
76 lemma [quot_respect]: |
47 shows "(op \<approx> ===> op \<approx> ===> op \<approx>) op @ op @" |
77 shows "(op \<approx> ===> op \<approx> ===> op \<approx>) op @ op @" |
48 by auto |
78 by auto |
49 |
79 |
|
80 lemma [quot_respect]: |
|
81 shows "(op \<approx> ===> op \<approx> ===> op =) sub_list sub_list" |
|
82 by (auto simp add: sub_list_def) |
|
83 |
|
84 lemma memb_rsp[quot_respect]: |
|
85 shows "(op = ===> op \<approx> ===> op =) memb memb" |
|
86 by (auto simp add: memb_def) |
|
87 |
|
88 lemma nil_rsp[quot_respect]: |
|
89 shows "[] \<approx> []" |
|
90 by simp |
|
91 |
|
92 lemma cons_rsp[quot_respect]: |
|
93 shows "(op = ===> op \<approx> ===> op \<approx>) op # op #" |
|
94 by simp |
|
95 |
|
96 lemma map_rsp[quot_respect]: |
|
97 shows "(op = ===> op \<approx> ===> op \<approx>) map map" |
|
98 by auto |
|
99 |
|
100 lemma set_rsp[quot_respect]: |
|
101 "(op \<approx> ===> op =) set set" |
|
102 by auto |
|
103 |
|
104 lemma list_equiv_rsp[quot_respect]: |
|
105 shows "(op \<approx> ===> op \<approx> ===> op =) op \<approx> op \<approx>" |
|
106 by auto |
|
107 |
|
108 lemma not_memb_nil: |
|
109 shows "\<not> memb x []" |
|
110 by (simp add: memb_def) |
|
111 |
|
112 lemma memb_cons_iff: |
|
113 shows "memb x (y # xs) = (x = y \<or> memb x xs)" |
|
114 by (induct xs) (auto simp add: memb_def) |
|
115 |
|
116 lemma memb_finter_raw: |
|
117 "memb x (finter_raw xs ys) \<longleftrightarrow> memb x xs \<and> memb x ys" |
|
118 by (induct xs) (auto simp add: not_memb_nil memb_cons_iff) |
|
119 |
|
120 lemma [quot_respect]: |
|
121 "(op \<approx> ===> op \<approx> ===> op \<approx>) finter_raw finter_raw" |
|
122 by (simp add: memb_def[symmetric] memb_finter_raw) |
|
123 |
|
124 lemma memb_delete_raw: |
|
125 "memb x (delete_raw xs y) = (memb x xs \<and> x \<noteq> y)" |
|
126 by (induct xs arbitrary: x y) (auto simp add: memb_def) |
|
127 |
|
128 lemma [quot_respect]: |
|
129 "(op \<approx> ===> op = ===> op \<approx>) delete_raw delete_raw" |
|
130 by (simp add: memb_def[symmetric] memb_delete_raw) |
|
131 |
|
132 lemma fcard_raw_gt_0: |
|
133 assumes a: "x \<in> set xs" |
|
134 shows "0 < fcard_raw xs" |
|
135 using a by (induct xs) (auto simp add: memb_def) |
|
136 |
|
137 lemma fcard_raw_delete_one: |
|
138 shows "fcard_raw ([x \<leftarrow> xs. x \<noteq> y]) = (if memb y xs then fcard_raw xs - 1 else fcard_raw xs)" |
|
139 by (induct xs) (auto dest: fcard_raw_gt_0 simp add: memb_def) |
|
140 |
|
141 lemma fcard_raw_rsp_aux: |
|
142 assumes a: "xs \<approx> ys" |
|
143 shows "fcard_raw xs = fcard_raw ys" |
|
144 using a |
|
145 apply (induct xs arbitrary: ys) |
|
146 apply (auto simp add: memb_def) |
|
147 apply (subgoal_tac "\<forall>x. (x \<in> set xs) = (x \<in> set ys)") |
|
148 apply (auto) |
|
149 apply (drule_tac x="x" in spec) |
|
150 apply (blast) |
|
151 apply (drule_tac x="[x \<leftarrow> ys. x \<noteq> a]" in meta_spec) |
|
152 apply (simp add: fcard_raw_delete_one memb_def) |
|
153 apply (case_tac "a \<in> set ys") |
|
154 apply (simp only: if_True) |
|
155 apply (subgoal_tac "\<forall>x. (x \<in> set xs) = (x \<in> set ys \<and> x \<noteq> a)") |
|
156 apply (drule Suc_pred'[OF fcard_raw_gt_0]) |
|
157 apply (auto) |
|
158 done |
|
159 |
|
160 lemma fcard_raw_rsp[quot_respect]: |
|
161 shows "(op \<approx> ===> op =) fcard_raw fcard_raw" |
|
162 by (simp add: fcard_raw_rsp_aux) |
|
163 |
|
164 lemma memb_absorb: |
|
165 shows "memb x xs \<Longrightarrow> x # xs \<approx> xs" |
|
166 by (induct xs) (auto simp add: memb_def) |
|
167 |
|
168 lemma none_memb_nil: |
|
169 "(\<forall>x. \<not> memb x xs) = (xs \<approx> [])" |
|
170 by (simp add: memb_def) |
|
171 |
|
172 lemma not_memb_delete_raw_ident: |
|
173 shows "\<not> memb x xs \<Longrightarrow> delete_raw xs x = xs" |
|
174 by (induct xs) (auto simp add: memb_def) |
|
175 |
|
176 lemma memb_commute_ffold_raw: |
|
177 "rsp_fold f \<Longrightarrow> memb h b \<Longrightarrow> ffold_raw f z b = f h (ffold_raw f z (delete_raw b h))" |
|
178 apply (induct b) |
|
179 apply (simp_all add: not_memb_nil) |
|
180 apply (auto) |
|
181 apply (simp_all add: memb_delete_raw not_memb_delete_raw_ident rsp_fold_def memb_cons_iff) |
|
182 done |
|
183 |
|
184 lemma ffold_raw_rsp_pre: |
|
185 "\<forall>e. memb e a = memb e b \<Longrightarrow> ffold_raw f z a = ffold_raw f z b" |
|
186 apply (induct a arbitrary: b) |
|
187 apply (simp add: memb_absorb memb_def none_memb_nil) |
|
188 apply (simp) |
|
189 apply (rule conjI) |
|
190 apply (rule_tac [!] impI) |
|
191 apply (rule_tac [!] conjI) |
|
192 apply (rule_tac [!] impI) |
|
193 apply (subgoal_tac "\<forall>e. memb e a2 = memb e b") |
|
194 apply (simp) |
|
195 apply (simp add: memb_cons_iff memb_def) |
|
196 apply (auto)[1] |
|
197 apply (drule_tac x="e" in spec) |
|
198 apply (blast) |
|
199 apply (case_tac b) |
|
200 apply (simp_all) |
|
201 apply (subgoal_tac "ffold_raw f z b = f a1 (ffold_raw f z (delete_raw b a1))") |
|
202 apply (simp only:) |
|
203 apply (rule_tac f="f a1" in arg_cong) |
|
204 apply (subgoal_tac "\<forall>e. memb e a2 = memb e (delete_raw b a1)") |
|
205 apply (simp) |
|
206 apply (simp add: memb_delete_raw) |
|
207 apply (auto simp add: memb_cons_iff)[1] |
|
208 apply (erule memb_commute_ffold_raw) |
|
209 apply (drule_tac x="a1" in spec) |
|
210 apply (simp add: memb_cons_iff) |
|
211 apply (simp add: memb_cons_iff) |
|
212 apply (case_tac b) |
|
213 apply (simp_all) |
|
214 done |
|
215 |
|
216 lemma [quot_respect]: |
|
217 "(op = ===> op = ===> op \<approx> ===> op =) ffold_raw ffold_raw" |
|
218 by (simp add: memb_def[symmetric] ffold_raw_rsp_pre) |
|
219 |
|
220 text {* Distributive lattice with bot *} |
|
221 |
50 lemma sub_list_not_eq: |
222 lemma sub_list_not_eq: |
51 "(sub_list x y \<and> \<not> list_eq x y) = (sub_list x y \<and> \<not> sub_list y x)" |
223 "(sub_list x y \<and> \<not> list_eq x y) = (sub_list x y \<and> \<not> sub_list y x)" |
52 by (auto simp add: sub_list_def) |
224 by (auto simp add: sub_list_def) |
53 |
225 |
54 lemma sub_list_refl: |
226 lemma sub_list_refl: |
61 |
233 |
62 lemma sub_list_empty: |
234 lemma sub_list_empty: |
63 "sub_list [] x" |
235 "sub_list [] x" |
64 by (simp add: sub_list_def) |
236 by (simp add: sub_list_def) |
65 |
237 |
66 instantiation fset :: (type) bot |
238 lemma sub_list_append_left: |
|
239 "sub_list x (x @ y)" |
|
240 by (simp add: sub_list_def) |
|
241 |
|
242 lemma sub_list_append_right: |
|
243 "sub_list y (x @ y)" |
|
244 by (simp add: sub_list_def) |
|
245 |
|
246 lemma sub_list_inter_left: |
|
247 shows "sub_list (finter_raw x y) x" |
|
248 by (simp add: sub_list_def memb_def[symmetric] memb_finter_raw) |
|
249 |
|
250 lemma sub_list_inter_right: |
|
251 shows "sub_list (finter_raw x y) y" |
|
252 by (simp add: sub_list_def memb_def[symmetric] memb_finter_raw) |
|
253 |
|
254 lemma sub_list_list_eq: |
|
255 "sub_list x y \<Longrightarrow> sub_list y x \<Longrightarrow> list_eq x y" |
|
256 unfolding sub_list_def list_eq.simps by blast |
|
257 |
|
258 lemma sub_list_append: |
|
259 "sub_list y x \<Longrightarrow> sub_list z x \<Longrightarrow> sub_list (y @ z) x" |
|
260 unfolding sub_list_def by auto |
|
261 |
|
262 lemma sub_list_inter: |
|
263 "sub_list x y \<Longrightarrow> sub_list x z \<Longrightarrow> sub_list x (finter_raw y z)" |
|
264 by (simp add: sub_list_def memb_def[symmetric] memb_finter_raw) |
|
265 |
|
266 lemma append_inter_distrib: |
|
267 "x @ (finter_raw y z) \<approx> finter_raw (x @ y) (x @ z)" |
|
268 apply (induct x) |
|
269 apply (simp_all add: memb_def) |
|
270 apply (simp add: memb_def[symmetric] memb_finter_raw) |
|
271 by (auto simp add: memb_def) |
|
272 |
|
273 instantiation fset :: (type) "{bot,distrib_lattice}" |
67 begin |
274 begin |
68 |
275 |
69 quotient_definition |
276 quotient_definition |
70 "bot :: 'a fset" is "[] :: 'a list" |
277 "bot :: 'a fset" is "[] :: 'a list" |
71 |
278 |
90 |
297 |
91 abbreviation |
298 abbreviation |
92 f_subset :: "'a fset \<Rightarrow> 'a fset \<Rightarrow> bool" (infix "|\<subset>|" 50) |
299 f_subset :: "'a fset \<Rightarrow> 'a fset \<Rightarrow> bool" (infix "|\<subset>|" 50) |
93 where |
300 where |
94 "xs |\<subset>| ys \<equiv> xs < ys" |
301 "xs |\<subset>| ys \<equiv> xs < ys" |
|
302 |
|
303 quotient_definition |
|
304 "sup \<Colon> ('a fset \<Rightarrow> 'a fset \<Rightarrow> 'a fset)" |
|
305 is |
|
306 "(op @) \<Colon> ('a list \<Rightarrow> 'a list \<Rightarrow> 'a list)" |
|
307 |
|
308 abbreviation |
|
309 funion (infixl "|\<union>|" 65) |
|
310 where |
|
311 "xs |\<union>| ys \<equiv> sup (xs :: 'a fset) ys" |
|
312 |
|
313 quotient_definition |
|
314 "inf \<Colon> ('a fset \<Rightarrow> 'a fset \<Rightarrow> 'a fset)" |
|
315 is |
|
316 "finter_raw \<Colon> ('a list \<Rightarrow> 'a list \<Rightarrow> 'a list)" |
|
317 |
|
318 abbreviation |
|
319 finter (infixl "|\<inter>|" 65) |
|
320 where |
|
321 "xs |\<inter>| ys \<equiv> inf (xs :: 'a fset) ys" |
95 |
322 |
96 instance |
323 instance |
97 proof |
324 proof |
98 fix x y z :: "'a fset" |
325 fix x y z :: "'a fset" |
99 show "(x |\<subset>| y) = (x |\<subseteq>| y \<and> \<not> y |\<subseteq>| x)" |
326 show "(x |\<subset>| y) = (x |\<subseteq>| y \<and> \<not> y |\<subseteq>| x)" |
100 unfolding less_fset by (lifting sub_list_not_eq) |
327 unfolding less_fset by (lifting sub_list_not_eq) |
101 show "x |\<subseteq>| x" by (lifting sub_list_refl) |
328 show "x |\<subseteq>| x" by (lifting sub_list_refl) |
102 show "{||} |\<subseteq>| x" by (lifting sub_list_empty) |
329 show "{||} |\<subseteq>| x" by (lifting sub_list_empty) |
|
330 show "x |\<subseteq>| x |\<union>| y" by (lifting sub_list_append_left) |
|
331 show "y |\<subseteq>| x |\<union>| y" by (lifting sub_list_append_right) |
|
332 show "x |\<inter>| y |\<subseteq>| x" by (lifting sub_list_inter_left) |
|
333 show "x |\<inter>| y |\<subseteq>| y" by (lifting sub_list_inter_right) |
|
334 show "x |\<union>| (y |\<inter>| z) = x |\<union>| y |\<inter>| (x |\<union>| z)" by (lifting append_inter_distrib) |
103 next |
335 next |
104 fix x y z :: "'a fset" |
336 fix x y z :: "'a fset" |
105 assume a: "x |\<subseteq>| y" |
337 assume a: "x |\<subseteq>| y" |
106 assume b: "y |\<subseteq>| z" |
338 assume b: "y |\<subseteq>| z" |
107 show "x |\<subseteq>| z" using a b by (lifting sub_list_trans) |
339 show "x |\<subseteq>| z" using a b by (lifting sub_list_trans) |
108 qed |
|
109 end |
|
110 |
|
111 lemma sub_list_append_left: |
|
112 "sub_list x (x @ y)" |
|
113 by (simp add: sub_list_def) |
|
114 |
|
115 lemma sub_list_append_right: |
|
116 "sub_list y (x @ y)" |
|
117 by (simp add: sub_list_def) |
|
118 |
|
119 lemma sub_list_list_eq: |
|
120 "sub_list x y \<Longrightarrow> sub_list y x \<Longrightarrow> list_eq x y" |
|
121 unfolding sub_list_def list_eq.simps by blast |
|
122 |
|
123 lemma sub_list_append: |
|
124 "sub_list y x \<Longrightarrow> sub_list z x \<Longrightarrow> sub_list (y @ z) x" |
|
125 unfolding sub_list_def by auto |
|
126 |
|
127 instantiation fset :: (type) "semilattice_sup" |
|
128 begin |
|
129 |
|
130 quotient_definition |
|
131 "sup \<Colon> ('a fset \<Rightarrow> 'a fset \<Rightarrow> 'a fset)" |
|
132 is |
|
133 "(op @) \<Colon> ('a list \<Rightarrow> 'a list \<Rightarrow> 'a list)" |
|
134 |
|
135 abbreviation |
|
136 funion (infixl "|\<union>|" 65) |
|
137 where |
|
138 "xs |\<union>| ys \<equiv> sup (xs :: 'a fset) ys" |
|
139 |
|
140 instance |
|
141 proof |
|
142 fix x y :: "'a fset" |
|
143 show "x |\<subseteq>| x |\<union>| y" by (lifting sub_list_append_left) |
|
144 show "y |\<subseteq>| x |\<union>| y" by (lifting sub_list_append_right) |
|
145 next |
340 next |
146 fix x y :: "'a fset" |
341 fix x y :: "'a fset" |
147 assume a: "x |\<subseteq>| y" |
342 assume a: "x |\<subseteq>| y" |
148 assume b: "y |\<subseteq>| x" |
343 assume b: "y |\<subseteq>| x" |
149 show "x = y" using a b by (lifting sub_list_list_eq) |
344 show "x = y" using a b by (lifting sub_list_list_eq) |
150 next |
345 next |
151 fix x y z :: "'a fset" |
346 fix x y z :: "'a fset" |
152 assume a: "y |\<subseteq>| x" |
347 assume a: "y |\<subseteq>| x" |
153 assume b: "z |\<subseteq>| x" |
348 assume b: "z |\<subseteq>| x" |
154 show "y |\<union>| z |\<subseteq>| x" using a b by (lifting sub_list_append) |
349 show "y |\<union>| z |\<subseteq>| x" using a b by (lifting sub_list_append) |
|
350 next |
|
351 fix x y z :: "'a fset" |
|
352 assume a: "x |\<subseteq>| y" |
|
353 assume b: "x |\<subseteq>| z" |
|
354 show "x |\<subseteq>| y |\<inter>| z" using a b by (lifting sub_list_inter) |
155 qed |
355 qed |
|
356 |
156 end |
357 end |
157 |
358 |
158 section {* Empty fset, Finsert and Membership *} |
359 section {* Finsert and Membership *} |
159 |
360 |
160 quotient_definition |
361 quotient_definition |
161 "finsert :: 'a \<Rightarrow> 'a fset \<Rightarrow> 'a fset" |
362 "finsert :: 'a \<Rightarrow> 'a fset \<Rightarrow> 'a fset" |
162 is "op #" |
363 is "op #" |
163 |
364 |
175 |
376 |
176 abbreviation |
377 abbreviation |
177 fnotin :: "'a \<Rightarrow> 'a fset \<Rightarrow> bool" ("_ |\<notin>| _" [50, 51] 50) |
378 fnotin :: "'a \<Rightarrow> 'a fset \<Rightarrow> bool" ("_ |\<notin>| _" [50, 51] 50) |
178 where |
379 where |
179 "x |\<notin>| S \<equiv> \<not> (x |\<in>| S)" |
380 "x |\<notin>| S \<equiv> \<not> (x |\<in>| S)" |
180 |
|
181 lemma memb_rsp[quot_respect]: |
|
182 shows "(op = ===> op \<approx> ===> op =) memb memb" |
|
183 by (auto simp add: memb_def) |
|
184 |
|
185 lemma nil_rsp[quot_respect]: |
|
186 shows "[] \<approx> []" |
|
187 by simp |
|
188 |
|
189 lemma cons_rsp[quot_respect]: |
|
190 shows "(op = ===> op \<approx> ===> op \<approx>) op # op #" |
|
191 by simp |
|
192 |
381 |
193 section {* Augmenting an fset -- @{const finsert} *} |
382 section {* Augmenting an fset -- @{const finsert} *} |
194 |
383 |
195 lemma nil_not_cons: |
384 lemma nil_not_cons: |
196 shows "\<not> ([] \<approx> x # xs)" |
385 shows "\<not> ([] \<approx> x # xs)" |
197 and "\<not> (x # xs \<approx> [])" |
386 and "\<not> (x # xs \<approx> [])" |
198 by auto |
387 by auto |
199 |
388 |
200 lemma not_memb_nil: |
|
201 shows "\<not> memb x []" |
|
202 by (simp add: memb_def) |
|
203 |
|
204 lemma no_memb_nil: |
389 lemma no_memb_nil: |
205 "(\<forall>x. \<not> memb x xs) = (xs = [])" |
390 "(\<forall>x. \<not> memb x xs) = (xs = [])" |
206 by (simp add: memb_def) |
391 by (simp add: memb_def) |
207 |
392 |
208 lemma none_memb_nil: |
|
209 "(\<forall>x. \<not> memb x xs) = (xs \<approx> [])" |
|
210 by (simp add: memb_def) |
|
211 |
|
212 lemma memb_cons_iff: |
|
213 shows "memb x (y # xs) = (x = y \<or> memb x xs)" |
|
214 by (induct xs) (auto simp add: memb_def) |
|
215 |
|
216 lemma memb_consI1: |
393 lemma memb_consI1: |
217 shows "memb x (x # xs)" |
394 shows "memb x (x # xs)" |
218 by (simp add: memb_def) |
395 by (simp add: memb_def) |
219 |
396 |
220 lemma memb_consI2: |
397 lemma memb_consI2: |
221 shows "memb x xs \<Longrightarrow> memb x (y # xs)" |
398 shows "memb x xs \<Longrightarrow> memb x (y # xs)" |
222 by (simp add: memb_def) |
399 by (simp add: memb_def) |
223 |
400 |
224 lemma memb_absorb: |
|
225 shows "memb x xs \<Longrightarrow> x # xs \<approx> xs" |
|
226 by (induct xs) (auto simp add: memb_def id_simps) |
|
227 |
|
228 section {* Singletons *} |
401 section {* Singletons *} |
229 |
402 |
230 lemma singleton_list_eq: |
403 lemma singleton_list_eq: |
231 shows "[x] \<approx> [y] \<longleftrightarrow> x = y" |
404 shows "[x] \<approx> [y] \<longleftrightarrow> x = y" |
232 by (simp add: id_simps) auto |
405 by (simp add: id_simps) auto |
380 apply (auto simp add: memb_def) |
508 apply (auto simp add: memb_def) |
381 done |
509 done |
382 |
510 |
383 section {* deletion *} |
511 section {* deletion *} |
384 |
512 |
385 fun |
|
386 delete_raw :: "'a list \<Rightarrow> 'a \<Rightarrow> 'a list" |
|
387 where |
|
388 "delete_raw [] x = []" |
|
389 | "delete_raw (a # A) x = (if (a = x) then delete_raw A x else a # (delete_raw A x))" |
|
390 |
|
391 lemma memb_delete_raw: |
|
392 "memb x (delete_raw xs y) = (memb x xs \<and> x \<noteq> y)" |
|
393 by (induct xs arbitrary: x y) (auto simp add: memb_def) |
|
394 |
|
395 lemma delete_raw_rsp: |
|
396 "xs \<approx> ys \<Longrightarrow> delete_raw xs x \<approx> delete_raw ys x" |
|
397 by (simp add: memb_def[symmetric] memb_delete_raw) |
|
398 |
|
399 lemma [quot_respect]: |
|
400 "(op \<approx> ===> op = ===> op \<approx>) delete_raw delete_raw" |
|
401 by (simp add: memb_def[symmetric] memb_delete_raw) |
|
402 |
|
403 lemma memb_delete_raw_ident: |
513 lemma memb_delete_raw_ident: |
404 shows "\<not> memb x (delete_raw xs x)" |
514 shows "\<not> memb x (delete_raw xs x)" |
405 by (induct xs) (auto simp add: memb_def) |
515 by (induct xs) (auto simp add: memb_def) |
406 |
516 |
407 lemma not_memb_delete_raw_ident: |
|
408 shows "\<not> memb x xs \<Longrightarrow> delete_raw xs x = xs" |
|
409 by (induct xs) (auto simp add: memb_def) |
|
410 |
|
411 lemma fset_raw_delete_raw_cases: |
517 lemma fset_raw_delete_raw_cases: |
412 "xs = [] \<or> (\<exists>x. memb x xs \<and> xs \<approx> x # delete_raw xs x)" |
518 "xs = [] \<or> (\<exists>x. memb x xs \<and> xs \<approx> x # delete_raw xs x)" |
413 by (induct xs) (auto simp add: memb_def) |
519 by (induct xs) (auto simp add: memb_def) |
414 |
520 |
415 lemma fdelete_raw_filter: |
521 lemma fdelete_raw_filter: |
418 |
524 |
419 lemma fcard_raw_delete: |
525 lemma fcard_raw_delete: |
420 "fcard_raw (delete_raw xs y) = (if memb y xs then fcard_raw xs - 1 else fcard_raw xs)" |
526 "fcard_raw (delete_raw xs y) = (if memb y xs then fcard_raw xs - 1 else fcard_raw xs)" |
421 by (simp add: fdelete_raw_filter fcard_raw_delete_one) |
527 by (simp add: fdelete_raw_filter fcard_raw_delete_one) |
422 |
528 |
423 lemma set_rsp[quot_respect]: |
529 |
424 "(op \<approx> ===> op =) set set" |
530 |
425 by auto |
531 |
426 |
|
427 definition |
|
428 rsp_fold |
|
429 where |
|
430 "rsp_fold f = (\<forall>u v w. (f u (f v w) = f v (f u w)))" |
|
431 |
|
432 primrec |
|
433 ffold_raw :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a list \<Rightarrow> 'b" |
|
434 where |
|
435 "ffold_raw f z [] = z" |
|
436 | "ffold_raw f z (a # A) = |
|
437 (if (rsp_fold f) then |
|
438 if memb a A then ffold_raw f z A |
|
439 else f a (ffold_raw f z A) |
|
440 else z)" |
|
441 |
|
442 lemma memb_commute_ffold_raw: |
|
443 "rsp_fold f \<Longrightarrow> memb h b \<Longrightarrow> ffold_raw f z b = f h (ffold_raw f z (delete_raw b h))" |
|
444 apply (induct b) |
|
445 apply (simp add: not_memb_nil) |
|
446 apply (simp add: ffold_raw.simps) |
|
447 apply (rule conjI) |
|
448 apply (rule_tac [!] impI) |
|
449 apply (rule_tac [!] conjI) |
|
450 apply (rule_tac [!] impI) |
|
451 apply (simp_all add: memb_delete_raw) |
|
452 apply (simp add: memb_cons_iff) |
|
453 apply (simp add: not_memb_delete_raw_ident) |
|
454 apply (simp add: memb_cons_iff rsp_fold_def) |
|
455 done |
|
456 |
|
457 lemma ffold_raw_rsp_pre: |
|
458 "\<forall>e. memb e a = memb e b \<Longrightarrow> ffold_raw f z a = ffold_raw f z b" |
|
459 apply (induct a arbitrary: b) |
|
460 apply (simp add: hd_in_set memb_absorb memb_def none_memb_nil) |
|
461 apply (simp add: ffold_raw.simps) |
|
462 apply (rule conjI) |
|
463 apply (rule_tac [!] impI) |
|
464 apply (rule_tac [!] conjI) |
|
465 apply (rule_tac [!] impI) |
|
466 apply (subgoal_tac "\<forall>e. memb e a2 = memb e b") |
|
467 apply (simp) |
|
468 apply (simp add: memb_cons_iff memb_def) |
|
469 apply auto |
|
470 apply (drule_tac x="e" in spec) |
|
471 apply blast |
|
472 apply (case_tac b) |
|
473 apply simp_all |
|
474 apply (subgoal_tac "ffold_raw f z b = f a1 (ffold_raw f z (delete_raw b a1))") |
|
475 apply (simp only:) |
|
476 apply (rule_tac f="f a1" in arg_cong) |
|
477 apply (subgoal_tac "\<forall>e. memb e a2 = memb e (delete_raw b a1)") |
|
478 apply simp |
|
479 apply (simp add: memb_delete_raw) |
|
480 apply (auto simp add: memb_cons_iff)[1] |
|
481 apply (erule memb_commute_ffold_raw) |
|
482 apply (drule_tac x="a1" in spec) |
|
483 apply (simp add: memb_cons_iff) |
|
484 apply (simp add: memb_cons_iff) |
|
485 apply (case_tac b) |
|
486 apply simp_all |
|
487 done |
|
488 |
|
489 lemma [quot_respect]: |
|
490 "(op = ===> op = ===> op \<approx> ===> op =) ffold_raw ffold_raw" |
|
491 by (simp add: memb_def[symmetric] ffold_raw_rsp_pre) |
|
492 |
|
493 primrec |
|
494 finter_raw :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" |
|
495 where |
|
496 "finter_raw [] l = []" |
|
497 | "finter_raw (h # t) l = |
|
498 (if memb h l then h # (finter_raw t l) else finter_raw t l)" |
|
499 |
532 |
500 lemma finter_raw_empty: |
533 lemma finter_raw_empty: |
501 "finter_raw l [] = []" |
534 "finter_raw l [] = []" |
502 by (induct l) (simp_all add: not_memb_nil) |
535 by (induct l) (simp_all add: not_memb_nil) |
503 |
536 |
504 lemma memb_finter_raw: |
|
505 "memb x (finter_raw xs ys) \<longleftrightarrow> memb x xs \<and> memb x ys" |
|
506 apply (induct xs) |
|
507 apply (simp add: not_memb_nil) |
|
508 apply (simp add: finter_raw.simps) |
|
509 apply (simp add: memb_cons_iff) |
|
510 apply auto |
|
511 done |
|
512 |
|
513 lemma [quot_respect]: |
|
514 "(op \<approx> ===> op \<approx> ===> op \<approx>) finter_raw finter_raw" |
|
515 by (simp add: memb_def[symmetric] memb_finter_raw) |
|
516 |
|
517 section {* Constants on the Quotient Type *} |
537 section {* Constants on the Quotient Type *} |
518 |
538 |
519 quotient_definition |
539 quotient_definition |
520 "fdelete :: 'a fset \<Rightarrow> 'a \<Rightarrow> 'a fset" |
540 "fdelete :: 'a fset \<Rightarrow> 'a \<Rightarrow> 'a fset" |
521 is "delete_raw" |
541 is "delete_raw" |