src/HOL/BNF/More_BNFs.thy
changeset 54841 af71b753c459
parent 54539 bbab2ebda234
child 55066 4e5ddf3162ac
equal deleted inserted replaced
54840:fac0c76bbda2 54841:af71b753c459
    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")