48 next |
48 next |
49 fix x |
49 fix x |
50 show "|Option.set x| \<le>o natLeq" |
50 show "|Option.set x| \<le>o natLeq" |
51 by (cases x) (simp_all add: ordLess_imp_ordLeq finite_iff_ordLess_natLeq[symmetric]) |
51 by (cases x) (simp_all add: ordLess_imp_ordLeq finite_iff_ordLess_natLeq[symmetric]) |
52 next |
52 next |
53 fix A B1 B2 f1 f2 p1 p2 |
53 fix R S |
54 assume wpull: "wpull A B1 B2 f1 f2 p1 p2" |
54 show "option_rel R OO option_rel S \<le> option_rel (R OO S)" |
55 show "wpull {x. Option.set x \<subseteq> A} {x. Option.set x \<subseteq> B1} {x. Option.set x \<subseteq> B2} |
55 by (auto simp: option_rel_def split: option.splits) |
56 (Option.map f1) (Option.map f2) (Option.map p1) (Option.map p2)" |
|
57 (is "wpull ?A ?B1 ?B2 ?f1 ?f2 ?p1 ?p2") |
|
58 unfolding wpull_def |
|
59 proof (intro strip, elim conjE) |
|
60 fix b1 b2 |
|
61 assume "b1 \<in> ?B1" "b2 \<in> ?B2" "?f1 b1 = ?f2 b2" |
|
62 thus "\<exists>a \<in> ?A. ?p1 a = b1 \<and> ?p2 a = b2" using wpull |
|
63 unfolding wpull_def by (cases b2) (auto 4 5) |
|
64 qed |
|
65 next |
56 next |
66 fix z |
57 fix z |
67 assume "z \<in> Option.set None" |
58 assume "z \<in> Option.set None" |
68 thus False by simp |
59 thus False by simp |
69 next |
60 next |
72 (Grp {x. Option.set x \<subseteq> Collect (split R)} (Option.map fst))\<inverse>\<inverse> OO |
63 (Grp {x. Option.set x \<subseteq> Collect (split R)} (Option.map fst))\<inverse>\<inverse> OO |
73 Grp {x. Option.set x \<subseteq> Collect (split R)} (Option.map snd)" |
64 Grp {x. Option.set x \<subseteq> Collect (split R)} (Option.map snd)" |
74 unfolding option_rel_def Grp_def relcompp.simps conversep.simps fun_eq_iff prod.cases |
65 unfolding option_rel_def Grp_def relcompp.simps conversep.simps fun_eq_iff prod.cases |
75 by (auto simp: trans[OF eq_commute option_map_is_None] trans[OF eq_commute option_map_eq_Some] |
66 by (auto simp: trans[OF eq_commute option_map_is_None] trans[OF eq_commute option_map_eq_Some] |
76 split: option.splits) |
67 split: option.splits) |
77 qed |
|
78 |
|
79 lemma wpull_map: |
|
80 assumes "wpull A B1 B2 f1 f2 p1 p2" |
|
81 shows "wpull {x. set x \<subseteq> A} {x. set x \<subseteq> B1} {x. set x \<subseteq> B2} (map f1) (map f2) (map p1) (map p2)" |
|
82 (is "wpull ?A ?B1 ?B2 _ _ _ _") |
|
83 proof (unfold wpull_def) |
|
84 { fix as bs assume *: "as \<in> ?B1" "bs \<in> ?B2" "map f1 as = map f2 bs" |
|
85 hence "length as = length bs" by (metis length_map) |
|
86 hence "\<exists>zs \<in> ?A. map p1 zs = as \<and> map p2 zs = bs" using * |
|
87 proof (induct as bs rule: list_induct2) |
|
88 case (Cons a as b bs) |
|
89 hence "a \<in> B1" "b \<in> B2" "f1 a = f2 b" by auto |
|
90 with assms obtain z where "z \<in> A" "p1 z = a" "p2 z = b" unfolding wpull_def by blast |
|
91 moreover |
|
92 from Cons obtain zs where "zs \<in> ?A" "map p1 zs = as" "map p2 zs = bs" by auto |
|
93 ultimately have "z # zs \<in> ?A" "map p1 (z # zs) = a # as \<and> map p2 (z # zs) = b # bs" by auto |
|
94 thus ?case by (rule_tac x = "z # zs" in bexI) |
|
95 qed simp |
|
96 } |
|
97 thus "\<forall>as bs. as \<in> ?B1 \<and> bs \<in> ?B2 \<and> map f1 as = map f2 bs \<longrightarrow> |
|
98 (\<exists>zs \<in> ?A. map p1 zs = as \<and> map p2 zs = bs)" by blast |
|
99 qed |
68 qed |
100 |
69 |
101 bnf "'a list" |
70 bnf "'a list" |
102 map: map |
71 map: map |
103 sets: set |
72 sets: set |
123 next |
92 next |
124 fix x |
93 fix x |
125 show "|set x| \<le>o natLeq" |
94 show "|set x| \<le>o natLeq" |
126 by (metis List.finite_set finite_iff_ordLess_natLeq ordLess_imp_ordLeq) |
95 by (metis List.finite_set finite_iff_ordLess_natLeq ordLess_imp_ordLeq) |
127 next |
96 next |
|
97 fix R S |
|
98 show "list_all2 R OO list_all2 S \<le> list_all2 (R OO S)" |
|
99 by (metis list_all2_OO order_refl) |
|
100 next |
128 fix R |
101 fix R |
129 show "list_all2 R = |
102 show "list_all2 R = |
130 (Grp {x. set x \<subseteq> {(x, y). R x y}} (map fst))\<inverse>\<inverse> OO |
103 (Grp {x. set x \<subseteq> {(x, y). R x y}} (map fst))\<inverse>\<inverse> OO |
131 Grp {x. set x \<subseteq> {(x, y). R x y}} (map snd)" |
104 Grp {x. set x \<subseteq> {(x, y). R x y}} (map snd)" |
132 unfolding list_all2_def[abs_def] Grp_def fun_eq_iff relcompp.simps conversep.simps |
105 unfolding list_all2_def[abs_def] Grp_def fun_eq_iff relcompp.simps conversep.simps |
133 by (force simp: zip_map_fst_snd) |
106 by (force simp: zip_map_fst_snd) |
134 qed (simp add: wpull_map)+ |
107 qed simp_all |
135 |
108 |
136 |
109 |
137 (* Finite sets *) |
110 (* Finite sets *) |
138 |
|
139 lemma wpull_image: |
|
140 assumes "wpull A B1 B2 f1 f2 p1 p2" |
|
141 shows "wpull (Pow A) (Pow B1) (Pow B2) (image f1) (image f2) (image p1) (image p2)" |
|
142 unfolding wpull_def Pow_def Bex_def mem_Collect_eq proof clarify |
|
143 fix Y1 Y2 assume Y1: "Y1 \<subseteq> B1" and Y2: "Y2 \<subseteq> B2" and EQ: "f1 ` Y1 = f2 ` Y2" |
|
144 def X \<equiv> "{a \<in> A. p1 a \<in> Y1 \<and> p2 a \<in> Y2}" |
|
145 show "\<exists>X\<subseteq>A. p1 ` X = Y1 \<and> p2 ` X = Y2" |
|
146 proof (rule exI[of _ X], intro conjI) |
|
147 show "p1 ` X = Y1" |
|
148 proof |
|
149 show "Y1 \<subseteq> p1 ` X" |
|
150 proof safe |
|
151 fix y1 assume y1: "y1 \<in> Y1" |
|
152 then obtain y2 where y2: "y2 \<in> Y2" and eq: "f1 y1 = f2 y2" using EQ by auto |
|
153 then obtain x where "x \<in> A" and "p1 x = y1" and "p2 x = y2" |
|
154 using assms y1 Y1 Y2 unfolding wpull_def by blast |
|
155 thus "y1 \<in> p1 ` X" unfolding X_def using y1 y2 by auto |
|
156 qed |
|
157 qed(unfold X_def, auto) |
|
158 show "p2 ` X = Y2" |
|
159 proof |
|
160 show "Y2 \<subseteq> p2 ` X" |
|
161 proof safe |
|
162 fix y2 assume y2: "y2 \<in> Y2" |
|
163 then obtain y1 where y1: "y1 \<in> Y1" and eq: "f1 y1 = f2 y2" using EQ by force |
|
164 then obtain x where "x \<in> A" and "p1 x = y1" and "p2 x = y2" |
|
165 using assms y2 Y1 Y2 unfolding wpull_def by blast |
|
166 thus "y2 \<in> p2 ` X" unfolding X_def using y1 y2 by auto |
|
167 qed |
|
168 qed(unfold X_def, auto) |
|
169 qed(unfold X_def, auto) |
|
170 qed |
|
171 |
111 |
172 context |
112 context |
173 includes fset.lifting |
113 includes fset.lifting |
174 begin |
114 begin |
175 |
115 |
204 apply (rule conjI) |
144 apply (rule conjI) |
205 apply (transfer, clarsimp, metis snd_conv) |
145 apply (transfer, clarsimp, metis snd_conv) |
206 by (transfer, clarsimp, metis fst_conv) |
146 by (transfer, clarsimp, metis fst_conv) |
207 qed |
147 qed |
208 |
148 |
209 lemma wpull_fimage: |
|
210 assumes "wpull A B1 B2 f1 f2 p1 p2" |
|
211 shows "wpull {x. fset x \<subseteq> A} {x. fset x \<subseteq> B1} {x. fset x \<subseteq> B2} |
|
212 (fimage f1) (fimage f2) (fimage p1) (fimage p2)" |
|
213 unfolding wpull_def Pow_def Bex_def mem_Collect_eq proof clarify |
|
214 fix y1 y2 |
|
215 assume Y1: "fset y1 \<subseteq> B1" and Y2: "fset y2 \<subseteq> B2" |
|
216 assume "fimage f1 y1 = fimage f2 y2" |
|
217 hence EQ: "f1 ` (fset y1) = f2 ` (fset y2)" by transfer simp |
|
218 with Y1 Y2 obtain X where X: "X \<subseteq> A" and Y1: "p1 ` X = fset y1" and Y2: "p2 ` X = fset y2" |
|
219 using wpull_image[OF assms] unfolding wpull_def Pow_def |
|
220 by (auto elim!: allE[of _ "fset y1"] allE[of _ "fset y2"]) |
|
221 have "\<forall> y1' \<in> fset y1. \<exists> x. x \<in> X \<and> y1' = p1 x" using Y1 by auto |
|
222 then obtain q1 where q1: "\<forall> y1' \<in> fset y1. q1 y1' \<in> X \<and> y1' = p1 (q1 y1')" by metis |
|
223 have "\<forall> y2' \<in> fset y2. \<exists> x. x \<in> X \<and> y2' = p2 x" using Y2 by auto |
|
224 then obtain q2 where q2: "\<forall> y2' \<in> fset y2. q2 y2' \<in> X \<and> y2' = p2 (q2 y2')" by metis |
|
225 def X' \<equiv> "q1 ` (fset y1) \<union> q2 ` (fset y2)" |
|
226 have X': "X' \<subseteq> A" and Y1: "p1 ` X' = fset y1" and Y2: "p2 ` X' = fset y2" |
|
227 using X Y1 Y2 q1 q2 unfolding X'_def by auto |
|
228 have fX': "finite X'" unfolding X'_def by transfer simp |
|
229 then obtain x where X'eq: "X' = fset x" by transfer simp |
|
230 show "\<exists>x. fset x \<subseteq> A \<and> fimage p1 x = y1 \<and> fimage p2 x = y2" |
|
231 using X' Y1 Y2 by (auto simp: X'eq intro!: exI[of _ "x"]) (transfer, blast)+ |
|
232 qed |
|
233 |
|
234 bnf "'a fset" |
149 bnf "'a fset" |
235 map: fimage |
150 map: fimage |
236 sets: fset |
151 sets: fset |
237 bd: natLeq |
152 bd: natLeq |
238 wits: "{||}" |
153 wits: "{||}" |
243 apply transfer apply force |
158 apply transfer apply force |
244 apply transfer' apply force |
159 apply transfer' apply force |
245 apply (rule natLeq_card_order) |
160 apply (rule natLeq_card_order) |
246 apply (rule natLeq_cinfinite) |
161 apply (rule natLeq_cinfinite) |
247 apply transfer apply (metis ordLess_imp_ordLeq finite_iff_ordLess_natLeq) |
162 apply transfer apply (metis ordLess_imp_ordLeq finite_iff_ordLess_natLeq) |
248 apply (erule wpull_fimage) |
163 apply (fastforce simp: fset_rel_alt) |
249 apply (simp add: Grp_def relcompp.simps conversep.simps fun_eq_iff fset_rel_alt fset_rel_aux) |
164 apply (simp add: Grp_def relcompp.simps conversep.simps fun_eq_iff fset_rel_alt fset_rel_aux) |
250 apply transfer apply simp |
165 apply transfer apply simp |
251 done |
166 done |
252 |
167 |
253 lemma fset_rel_fset: "set_rel \<chi> (fset A1) (fset A2) = fset_rel \<chi> A1 A2" |
168 lemma fset_rel_fset: "set_rel \<chi> (fset A1) (fset A2) = fset_rel \<chi> A1 A2" |
547 shows "finite {u b1 b2 |b1 b2. b1 \<in> B1 \<and> b2 \<in> B2}" (is "finite ?A") |
462 shows "finite {u b1 b2 |b1 b2. b1 \<in> B1 \<and> b2 \<in> B2}" (is "finite ?A") |
548 proof- |
463 proof- |
549 have A: "?A = (\<lambda> b1b2. u (fst b1b2) (snd b1b2)) ` (B1 <*> B2)" by force |
464 have A: "?A = (\<lambda> b1b2. u (fst b1b2) (snd b1b2)) ` (B1 <*> B2)" by force |
550 show ?thesis unfolding A using finite_cartesian_product[OF assms] by auto |
465 show ?thesis unfolding A using finite_cartesian_product[OF assms] by auto |
551 qed |
466 qed |
|
467 |
|
468 (* Weak pullbacks: *) |
|
469 definition wpull where |
|
470 "wpull A B1 B2 f1 f2 p1 p2 \<longleftrightarrow> |
|
471 (\<forall> b1 b2. b1 \<in> B1 \<and> b2 \<in> B2 \<and> f1 b1 = f2 b2 \<longrightarrow> (\<exists> a \<in> A. p1 a = b1 \<and> p2 a = b2))" |
|
472 |
|
473 (* Weak pseudo-pullbacks *) |
|
474 definition wppull where |
|
475 "wppull A B1 B2 f1 f2 e1 e2 p1 p2 \<longleftrightarrow> |
|
476 (\<forall> b1 b2. b1 \<in> B1 \<and> b2 \<in> B2 \<and> f1 b1 = f2 b2 \<longrightarrow> |
|
477 (\<exists> a \<in> A. e1 (p1 a) = e1 b1 \<and> e2 (p2 a) = e2 b2))" |
|
478 |
|
479 |
|
480 (* The pullback of sets *) |
|
481 definition thePull where |
|
482 "thePull B1 B2 f1 f2 = {(b1,b2). b1 \<in> B1 \<and> b2 \<in> B2 \<and> f1 b1 = f2 b2}" |
|
483 |
|
484 lemma wpull_thePull: |
|
485 "wpull (thePull B1 B2 f1 f2) B1 B2 f1 f2 fst snd" |
|
486 unfolding wpull_def thePull_def by auto |
|
487 |
|
488 lemma wppull_thePull: |
|
489 assumes "wppull A B1 B2 f1 f2 e1 e2 p1 p2" |
|
490 shows |
|
491 "\<exists> j. \<forall> a' \<in> thePull B1 B2 f1 f2. |
|
492 j a' \<in> A \<and> |
|
493 e1 (p1 (j a')) = e1 (fst a') \<and> e2 (p2 (j a')) = e2 (snd a')" |
|
494 (is "\<exists> j. \<forall> a' \<in> ?A'. ?phi a' (j a')") |
|
495 proof(rule bchoice[of ?A' ?phi], default) |
|
496 fix a' assume a': "a' \<in> ?A'" |
|
497 hence "fst a' \<in> B1" unfolding thePull_def by auto |
|
498 moreover |
|
499 from a' have "snd a' \<in> B2" unfolding thePull_def by auto |
|
500 moreover have "f1 (fst a') = f2 (snd a')" |
|
501 using a' unfolding csquare_def thePull_def by auto |
|
502 ultimately show "\<exists> ja'. ?phi a' ja'" |
|
503 using assms unfolding wppull_def by blast |
|
504 qed |
|
505 |
|
506 lemma wpull_wppull: |
|
507 assumes wp: "wpull A' B1 B2 f1 f2 p1' p2'" and |
|
508 1: "\<forall> a' \<in> A'. j a' \<in> A \<and> e1 (p1 (j a')) = e1 (p1' a') \<and> e2 (p2 (j a')) = e2 (p2' a')" |
|
509 shows "wppull A B1 B2 f1 f2 e1 e2 p1 p2" |
|
510 unfolding wppull_def proof safe |
|
511 fix b1 b2 |
|
512 assume b1: "b1 \<in> B1" and b2: "b2 \<in> B2" and f: "f1 b1 = f2 b2" |
|
513 then obtain a' where a': "a' \<in> A'" and b1: "b1 = p1' a'" and b2: "b2 = p2' a'" |
|
514 using wp unfolding wpull_def by blast |
|
515 show "\<exists>a\<in>A. e1 (p1 a) = e1 b1 \<and> e2 (p2 a) = e2 b2" |
|
516 apply (rule bexI[of _ "j a'"]) unfolding b1 b2 using a' 1 by auto |
|
517 qed |
|
518 |
|
519 lemma wppull_fstOp_sndOp: |
|
520 shows "wppull (Collect (split (P OO Q))) (Collect (split P)) (Collect (split Q)) |
|
521 snd fst fst snd (fstOp P Q) (sndOp P Q)" |
|
522 using pick_middlep unfolding wppull_def fstOp_def sndOp_def relcompp.simps by auto |
552 |
523 |
553 lemma wpull_mmap: |
524 lemma wpull_mmap: |
554 fixes A :: "'a set" and B1 :: "'b1 set" and B2 :: "'b2 set" |
525 fixes A :: "'a set" and B1 :: "'b1 set" and B2 :: "'b2 set" |
555 assumes wp: "wpull A B1 B2 f1 f2 p1 p2" |
526 assumes wp: "wpull A B1 B2 f1 f2 p1 p2" |
556 shows |
527 shows |
779 |
750 |
780 lemma set_of_bd: "|set_of x| \<le>o natLeq" |
751 lemma set_of_bd: "|set_of x| \<le>o natLeq" |
781 by transfer |
752 by transfer |
782 (auto intro!: ordLess_imp_ordLeq simp: finite_iff_ordLess_natLeq[symmetric] multiset_def) |
753 (auto intro!: ordLess_imp_ordLeq simp: finite_iff_ordLess_natLeq[symmetric] multiset_def) |
783 |
754 |
|
755 lemma wppull_mmap: |
|
756 assumes "wppull A B1 B2 f1 f2 e1 e2 p1 p2" |
|
757 shows "wppull {M. set_of M \<subseteq> A} {N1. set_of N1 \<subseteq> B1} {N2. set_of N2 \<subseteq> B2} |
|
758 (mmap f1) (mmap f2) (mmap e1) (mmap e2) (mmap p1) (mmap p2)" |
|
759 proof - |
|
760 from assms obtain j where j: "\<forall>a'\<in>thePull B1 B2 f1 f2. |
|
761 j a' \<in> A \<and> e1 (p1 (j a')) = e1 (fst a') \<and> e2 (p2 (j a')) = e2 (snd a')" |
|
762 by (blast dest: wppull_thePull) |
|
763 then show ?thesis |
|
764 by (intro wpull_wppull[OF wpull_mmap[OF wpull_thePull], of _ _ _ _ "mmap j"]) |
|
765 (auto simp: o_eq_dest_lhs[OF mmap_comp[symmetric]] o_eq_dest[OF set_of_mmap] |
|
766 intro!: mmap_cong simp del: mem_set_of_iff simp: mem_set_of_iff[symmetric]) |
|
767 qed |
|
768 |
784 bnf "'a multiset" |
769 bnf "'a multiset" |
785 map: mmap |
770 map: mmap |
786 sets: set_of |
771 sets: set_of |
787 bd: natLeq |
772 bd: natLeq |
788 wits: "{#}" |
773 wits: "{#}" |
789 by (auto simp add: mmap_id0 mmap_comp set_of_mmap natLeq_card_order natLeq_cinfinite set_of_bd |
774 by (auto simp add: mmap_id0 mmap_comp set_of_mmap natLeq_card_order natLeq_cinfinite set_of_bd |
790 intro: mmap_cong wpull_mmap) |
775 Grp_def relcompp.simps intro: mmap_cong) |
|
776 (metis wppull_mmap[OF wppull_fstOp_sndOp, unfolded wppull_def |
|
777 o_eq_dest_lhs[OF mmap_comp[symmetric]] fstOp_def sndOp_def o_def, simplified]) |
791 |
778 |
792 inductive rel_multiset' where |
779 inductive rel_multiset' where |
793 Zero: "rel_multiset' R {#} {#}" |
780 Zero[intro]: "rel_multiset' R {#} {#}" |
794 | |
781 | Plus[intro]: "\<lbrakk>R a b; rel_multiset' R M N\<rbrakk> \<Longrightarrow> rel_multiset' R (M + {#a#}) (N + {#b#})" |
795 Plus: "\<lbrakk>R a b; rel_multiset' R M N\<rbrakk> \<Longrightarrow> rel_multiset' R (M + {#a#}) (N + {#b#})" |
|
796 |
782 |
797 lemma map_multiset_Zero_iff[simp]: "mmap f M = {#} \<longleftrightarrow> M = {#}" |
783 lemma map_multiset_Zero_iff[simp]: "mmap f M = {#} \<longleftrightarrow> M = {#}" |
798 by (metis image_is_empty multiset.set_map set_of_eq_empty_iff) |
784 by (metis image_is_empty multiset.set_map set_of_eq_empty_iff) |
799 |
785 |
800 lemma map_multiset_Zero[simp]: "mmap f {#} = {#}" by simp |
786 lemma map_multiset_Zero[simp]: "mmap f {#} = {#}" by simp |
996 |
982 |
997 |
983 |
998 (* Advanced relator customization *) |
984 (* Advanced relator customization *) |
999 |
985 |
1000 (* Set vs. sum relators: *) |
986 (* Set vs. sum relators: *) |
1001 (* FIXME: All such facts should be declared as simps: *) |
|
1002 declare sum_rel_simps[simp] |
|
1003 |
987 |
1004 lemma set_rel_sum_rel[simp]: |
988 lemma set_rel_sum_rel[simp]: |
1005 "set_rel (sum_rel \<chi> \<phi>) A1 A2 \<longleftrightarrow> |
989 "set_rel (sum_rel \<chi> \<phi>) A1 A2 \<longleftrightarrow> |
1006 set_rel \<chi> (Inl -` A1) (Inl -` A2) \<and> set_rel \<phi> (Inr -` A1) (Inr -` A2)" |
990 set_rel \<chi> (Inl -` A1) (Inl -` A2) \<and> set_rel \<phi> (Inr -` A1) (Inr -` A2)" |
1007 (is "?L \<longleftrightarrow> ?Rl \<and> ?Rr") |
991 (is "?L \<longleftrightarrow> ?Rl \<and> ?Rr") |