src/HOL/Library/Multiset.thy
changeset 60515 484559628038
parent 60513 55c7316f76d6
child 60606 e5cb9271e339
equal deleted inserted replaced
60514:78a82c37b4b2 60515:484559628038
   961   by (metis image_mset_cong split_cong)
   961   by (metis image_mset_cong split_cong)
   962 
   962 
   963 
   963 
   964 subsection \<open>Further conversions\<close>
   964 subsection \<open>Further conversions\<close>
   965 
   965 
   966 primrec multiset_of :: "'a list \<Rightarrow> 'a multiset" where
   966 primrec mset :: "'a list \<Rightarrow> 'a multiset" where
   967   "multiset_of [] = {#}" |
   967   "mset [] = {#}" |
   968   "multiset_of (a # x) = multiset_of x + {# a #}"
   968   "mset (a # x) = mset x + {# a #}"
   969 
   969 
   970 lemma in_multiset_in_set:
   970 lemma in_multiset_in_set:
   971   "x \<in># multiset_of xs \<longleftrightarrow> x \<in> set xs"
   971   "x \<in># mset xs \<longleftrightarrow> x \<in> set xs"
   972   by (induct xs) simp_all
   972   by (induct xs) simp_all
   973 
   973 
   974 lemma count_multiset_of:
   974 lemma count_mset:
   975   "count (multiset_of xs) x = length (filter (\<lambda>y. x = y) xs)"
   975   "count (mset xs) x = length (filter (\<lambda>y. x = y) xs)"
   976   by (induct xs) simp_all
   976   by (induct xs) simp_all
   977 
   977 
   978 lemma multiset_of_zero_iff[simp]: "(multiset_of x = {#}) = (x = [])"
   978 lemma mset_zero_iff[simp]: "(mset x = {#}) = (x = [])"
   979   by (induct x) auto
   979   by (induct x) auto
   980 
   980 
   981 lemma multiset_of_zero_iff_right[simp]: "({#} = multiset_of x) = (x = [])"
   981 lemma mset_zero_iff_right[simp]: "({#} = mset x) = (x = [])"
   982 by (induct x) auto
   982 by (induct x) auto
   983 
   983 
   984 lemma set_mset_multiset_of[simp]: "set_mset (multiset_of x) = set x"
   984 lemma set_mset_mset[simp]: "set_mset (mset x) = set x"
   985 by (induct x) auto
   985 by (induct x) auto
   986 
   986 
   987 lemma mem_set_multiset_eq: "x \<in> set xs = (x :# multiset_of xs)"
   987 lemma mem_set_multiset_eq: "x \<in> set xs = (x :# mset xs)"
   988 by (induct xs) auto
   988 by (induct xs) auto
   989 
   989 
   990 lemma size_multiset_of [simp]: "size (multiset_of xs) = length xs"
   990 lemma size_mset [simp]: "size (mset xs) = length xs"
   991   by (induct xs) simp_all
   991   by (induct xs) simp_all
   992 
   992 
   993 lemma multiset_of_append [simp]:
   993 lemma mset_append [simp]:
   994   "multiset_of (xs @ ys) = multiset_of xs + multiset_of ys"
   994   "mset (xs @ ys) = mset xs + mset ys"
   995   by (induct xs arbitrary: ys) (auto simp: ac_simps)
   995   by (induct xs arbitrary: ys) (auto simp: ac_simps)
   996 
   996 
   997 lemma multiset_of_filter:
   997 lemma mset_filter:
   998   "multiset_of (filter P xs) = {#x :# multiset_of xs. P x #}"
   998   "mset (filter P xs) = {#x :# mset xs. P x #}"
   999   by (induct xs) simp_all
   999   by (induct xs) simp_all
  1000 
  1000 
  1001 lemma multiset_of_rev [simp]:
  1001 lemma mset_rev [simp]:
  1002   "multiset_of (rev xs) = multiset_of xs"
  1002   "mset (rev xs) = mset xs"
  1003   by (induct xs) simp_all
  1003   by (induct xs) simp_all
  1004 
  1004 
  1005 lemma surj_multiset_of: "surj multiset_of"
  1005 lemma surj_mset: "surj mset"
  1006 apply (unfold surj_def)
  1006 apply (unfold surj_def)
  1007 apply (rule allI)
  1007 apply (rule allI)
  1008 apply (rule_tac M = y in multiset_induct)
  1008 apply (rule_tac M = y in multiset_induct)
  1009  apply auto
  1009  apply auto
  1010 apply (rule_tac x = "x # xa" in exI)
  1010 apply (rule_tac x = "x # xa" in exI)
  1011 apply auto
  1011 apply auto
  1012 done
  1012 done
  1013 
  1013 
  1014 lemma set_count_greater_0: "set x = {a. count (multiset_of x) a > 0}"
  1014 lemma set_count_greater_0: "set x = {a. count (mset x) a > 0}"
  1015 by (induct x) auto
  1015 by (induct x) auto
  1016 
  1016 
  1017 lemma distinct_count_atmost_1:
  1017 lemma distinct_count_atmost_1:
  1018   "distinct x = (! a. count (multiset_of x) a = (if a \<in> set x then 1 else 0))"
  1018   "distinct x = (! a. count (mset x) a = (if a \<in> set x then 1 else 0))"
  1019 apply (induct x, simp, rule iffI, simp_all)
  1019 apply (induct x, simp, rule iffI, simp_all)
  1020 apply (rename_tac a b)
  1020 apply (rename_tac a b)
  1021 apply (rule conjI)
  1021 apply (rule conjI)
  1022 apply (simp_all add: set_mset_multiset_of [THEN sym] del: set_mset_multiset_of)
  1022 apply (simp_all add: set_mset_mset [THEN sym] del: set_mset_mset)
  1023 apply (erule_tac x = a in allE, simp, clarify)
  1023 apply (erule_tac x = a in allE, simp, clarify)
  1024 apply (erule_tac x = aa in allE, simp)
  1024 apply (erule_tac x = aa in allE, simp)
  1025 done
  1025 done
  1026 
  1026 
  1027 lemma multiset_of_eq_setD:
  1027 lemma mset_eq_setD:
  1028   "multiset_of xs = multiset_of ys \<Longrightarrow> set xs = set ys"
  1028   "mset xs = mset ys \<Longrightarrow> set xs = set ys"
  1029 by (rule) (auto simp add:multiset_eq_iff set_count_greater_0)
  1029 by (rule) (auto simp add:multiset_eq_iff set_count_greater_0)
  1030 
  1030 
  1031 lemma set_eq_iff_multiset_of_eq_distinct:
  1031 lemma set_eq_iff_mset_eq_distinct:
  1032   "distinct x \<Longrightarrow> distinct y \<Longrightarrow>
  1032   "distinct x \<Longrightarrow> distinct y \<Longrightarrow>
  1033     (set x = set y) = (multiset_of x = multiset_of y)"
  1033     (set x = set y) = (mset x = mset y)"
  1034 by (auto simp: multiset_eq_iff distinct_count_atmost_1)
  1034 by (auto simp: multiset_eq_iff distinct_count_atmost_1)
  1035 
  1035 
  1036 lemma set_eq_iff_multiset_of_remdups_eq:
  1036 lemma set_eq_iff_mset_remdups_eq:
  1037    "(set x = set y) = (multiset_of (remdups x) = multiset_of (remdups y))"
  1037    "(set x = set y) = (mset (remdups x) = mset (remdups y))"
  1038 apply (rule iffI)
  1038 apply (rule iffI)
  1039 apply (simp add: set_eq_iff_multiset_of_eq_distinct[THEN iffD1])
  1039 apply (simp add: set_eq_iff_mset_eq_distinct[THEN iffD1])
  1040 apply (drule distinct_remdups [THEN distinct_remdups
  1040 apply (drule distinct_remdups [THEN distinct_remdups
  1041       [THEN set_eq_iff_multiset_of_eq_distinct [THEN iffD2]]])
  1041       [THEN set_eq_iff_mset_eq_distinct [THEN iffD2]]])
  1042 apply simp
  1042 apply simp
  1043 done
  1043 done
  1044 
  1044 
  1045 lemma multiset_of_compl_union [simp]:
  1045 lemma mset_compl_union [simp]:
  1046   "multiset_of [x\<leftarrow>xs. P x] + multiset_of [x\<leftarrow>xs. \<not>P x] = multiset_of xs"
  1046   "mset [x\<leftarrow>xs. P x] + mset [x\<leftarrow>xs. \<not>P x] = mset xs"
  1047   by (induct xs) (auto simp: ac_simps)
  1047   by (induct xs) (auto simp: ac_simps)
  1048 
  1048 
  1049 lemma nth_mem_multiset_of: "i < length ls \<Longrightarrow> (ls ! i) :# multiset_of ls"
  1049 lemma nth_mem_mset: "i < length ls \<Longrightarrow> (ls ! i) :# mset ls"
  1050 apply (induct ls arbitrary: i)
  1050 apply (induct ls arbitrary: i)
  1051  apply simp
  1051  apply simp
  1052 apply (case_tac i)
  1052 apply (case_tac i)
  1053  apply auto
  1053  apply auto
  1054 done
  1054 done
  1055 
  1055 
  1056 lemma multiset_of_remove1[simp]:
  1056 lemma mset_remove1[simp]:
  1057   "multiset_of (remove1 a xs) = multiset_of xs - {#a#}"
  1057   "mset (remove1 a xs) = mset xs - {#a#}"
  1058 by (induct xs) (auto simp add: multiset_eq_iff)
  1058 by (induct xs) (auto simp add: multiset_eq_iff)
  1059 
  1059 
  1060 lemma multiset_of_eq_length:
  1060 lemma mset_eq_length:
  1061   assumes "multiset_of xs = multiset_of ys"
  1061   assumes "mset xs = mset ys"
  1062   shows "length xs = length ys"
  1062   shows "length xs = length ys"
  1063   using assms by (metis size_multiset_of)
  1063   using assms by (metis size_mset)
  1064 
  1064 
  1065 lemma multiset_of_eq_length_filter:
  1065 lemma mset_eq_length_filter:
  1066   assumes "multiset_of xs = multiset_of ys"
  1066   assumes "mset xs = mset ys"
  1067   shows "length (filter (\<lambda>x. z = x) xs) = length (filter (\<lambda>y. z = y) ys)"
  1067   shows "length (filter (\<lambda>x. z = x) xs) = length (filter (\<lambda>y. z = y) ys)"
  1068   using assms by (metis count_multiset_of)
  1068   using assms by (metis count_mset)
  1069 
  1069 
  1070 lemma fold_multiset_equiv:
  1070 lemma fold_multiset_equiv:
  1071   assumes f: "\<And>x y. x \<in> set xs \<Longrightarrow> y \<in> set xs \<Longrightarrow> f x \<circ> f y = f y \<circ> f x"
  1071   assumes f: "\<And>x y. x \<in> set xs \<Longrightarrow> y \<in> set xs \<Longrightarrow> f x \<circ> f y = f y \<circ> f x"
  1072     and equiv: "multiset_of xs = multiset_of ys"
  1072     and equiv: "mset xs = mset ys"
  1073   shows "List.fold f xs = List.fold f ys"
  1073   shows "List.fold f xs = List.fold f ys"
  1074 using f equiv [symmetric]
  1074 using f equiv [symmetric]
  1075 proof (induct xs arbitrary: ys)
  1075 proof (induct xs arbitrary: ys)
  1076   case Nil then show ?case by simp
  1076   case Nil then show ?case by simp
  1077 next
  1077 next
  1078   case (Cons x xs)
  1078   case (Cons x xs)
  1079   then have *: "set ys = set (x # xs)" by (blast dest: multiset_of_eq_setD)
  1079   then have *: "set ys = set (x # xs)" by (blast dest: mset_eq_setD)
  1080   have "\<And>x y. x \<in> set ys \<Longrightarrow> y \<in> set ys \<Longrightarrow> f x \<circ> f y = f y \<circ> f x"
  1080   have "\<And>x y. x \<in> set ys \<Longrightarrow> y \<in> set ys \<Longrightarrow> f x \<circ> f y = f y \<circ> f x"
  1081     by (rule Cons.prems(1)) (simp_all add: *)
  1081     by (rule Cons.prems(1)) (simp_all add: *)
  1082   moreover from * have "x \<in> set ys" by simp
  1082   moreover from * have "x \<in> set ys" by simp
  1083   ultimately have "List.fold f ys = List.fold f (remove1 x ys) \<circ> f x" by (fact fold_remove1_split)
  1083   ultimately have "List.fold f ys = List.fold f (remove1 x ys) \<circ> f x" by (fact fold_remove1_split)
  1084   moreover from Cons.prems have "List.fold f xs = List.fold f (remove1 x ys)" by (auto intro: Cons.hyps)
  1084   moreover from Cons.prems have "List.fold f xs = List.fold f (remove1 x ys)" by (auto intro: Cons.hyps)
  1085   ultimately show ?case by simp
  1085   ultimately show ?case by simp
  1086 qed
  1086 qed
  1087 
  1087 
  1088 lemma multiset_of_insort [simp]:
  1088 lemma mset_insort [simp]:
  1089   "multiset_of (insort x xs) = multiset_of xs + {#x#}"
  1089   "mset (insort x xs) = mset xs + {#x#}"
  1090   by (induct xs) (simp_all add: ac_simps)
  1090   by (induct xs) (simp_all add: ac_simps)
  1091 
  1091 
  1092 lemma multiset_of_map:
  1092 lemma mset_map:
  1093   "multiset_of (map f xs) = image_mset f (multiset_of xs)"
  1093   "mset (map f xs) = image_mset f (mset xs)"
  1094   by (induct xs) simp_all
  1094   by (induct xs) simp_all
  1095 
  1095 
  1096 definition mset_set :: "'a set \<Rightarrow> 'a multiset"
  1096 definition mset_set :: "'a set \<Rightarrow> 'a multiset"
  1097 where
  1097 where
  1098   "mset_set = folding.F (\<lambda>x M. {#x#} + M) {#}"
  1098   "mset_set = folding.F (\<lambda>x M. {#x#} + M) {#}"
  1152   show ?thesis by (simp add: sorted_list_of_multiset_def)
  1152   show ?thesis by (simp add: sorted_list_of_multiset_def)
  1153 qed
  1153 qed
  1154 
  1154 
  1155 end
  1155 end
  1156 
  1156 
  1157 lemma multiset_of_sorted_list_of_multiset [simp]:
  1157 lemma mset_sorted_list_of_multiset [simp]:
  1158   "multiset_of (sorted_list_of_multiset M) = M"
  1158   "mset (sorted_list_of_multiset M) = M"
  1159 by (induct M) simp_all
  1159 by (induct M) simp_all
  1160 
  1160 
  1161 lemma sorted_list_of_multiset_multiset_of [simp]:
  1161 lemma sorted_list_of_multiset_mset [simp]:
  1162   "sorted_list_of_multiset (multiset_of xs) = sort xs"
  1162   "sorted_list_of_multiset (mset xs) = sort xs"
  1163 by (induct xs) simp_all
  1163 by (induct xs) simp_all
  1164 
  1164 
  1165 lemma finite_set_mset_mset_set[simp]:
  1165 lemma finite_set_mset_mset_set[simp]:
  1166   "finite A \<Longrightarrow> set_mset (mset_set A) = A"
  1166   "finite A \<Longrightarrow> set_mset (mset_set A) = A"
  1167 by (induct A rule: finite_induct) simp_all
  1167 by (induct A rule: finite_induct) simp_all
  1384 subsubsection \<open>Lists\<close>
  1384 subsubsection \<open>Lists\<close>
  1385 
  1385 
  1386 context linorder
  1386 context linorder
  1387 begin
  1387 begin
  1388 
  1388 
  1389 lemma multiset_of_insort [simp]:
  1389 lemma mset_insort [simp]:
  1390   "multiset_of (insort_key k x xs) = {#x#} + multiset_of xs"
  1390   "mset (insort_key k x xs) = {#x#} + mset xs"
  1391   by (induct xs) (simp_all add: ac_simps)
  1391   by (induct xs) (simp_all add: ac_simps)
  1392 
  1392 
  1393 lemma multiset_of_sort [simp]:
  1393 lemma mset_sort [simp]:
  1394   "multiset_of (sort_key k xs) = multiset_of xs"
  1394   "mset (sort_key k xs) = mset xs"
  1395   by (induct xs) (simp_all add: ac_simps)
  1395   by (induct xs) (simp_all add: ac_simps)
  1396 
  1396 
  1397 text \<open>
  1397 text \<open>
  1398   This lemma shows which properties suffice to show that a function
  1398   This lemma shows which properties suffice to show that a function
  1399   @{text "f"} with @{text "f xs = ys"} behaves like sort.
  1399   @{text "f"} with @{text "f xs = ys"} behaves like sort.
  1400 \<close>
  1400 \<close>
  1401 
  1401 
  1402 lemma properties_for_sort_key:
  1402 lemma properties_for_sort_key:
  1403   assumes "multiset_of ys = multiset_of xs"
  1403   assumes "mset ys = mset xs"
  1404   and "\<And>k. k \<in> set ys \<Longrightarrow> filter (\<lambda>x. f k = f x) ys = filter (\<lambda>x. f k = f x) xs"
  1404   and "\<And>k. k \<in> set ys \<Longrightarrow> filter (\<lambda>x. f k = f x) ys = filter (\<lambda>x. f k = f x) xs"
  1405   and "sorted (map f ys)"
  1405   and "sorted (map f ys)"
  1406   shows "sort_key f xs = ys"
  1406   shows "sort_key f xs = ys"
  1407 using assms
  1407 using assms
  1408 proof (induct xs arbitrary: ys)
  1408 proof (induct xs arbitrary: ys)
  1418     by (auto simp add: mem_set_multiset_eq intro!: ccontr)
  1418     by (auto simp add: mem_set_multiset_eq intro!: ccontr)
  1419   ultimately show ?case using Cons.prems by (simp add: insort_key_remove1)
  1419   ultimately show ?case using Cons.prems by (simp add: insort_key_remove1)
  1420 qed
  1420 qed
  1421 
  1421 
  1422 lemma properties_for_sort:
  1422 lemma properties_for_sort:
  1423   assumes multiset: "multiset_of ys = multiset_of xs"
  1423   assumes multiset: "mset ys = mset xs"
  1424   and "sorted ys"
  1424   and "sorted ys"
  1425   shows "sort xs = ys"
  1425   shows "sort xs = ys"
  1426 proof (rule properties_for_sort_key)
  1426 proof (rule properties_for_sort_key)
  1427   from multiset show "multiset_of ys = multiset_of xs" .
  1427   from multiset show "mset ys = mset xs" .
  1428   from \<open>sorted ys\<close> show "sorted (map (\<lambda>x. x) ys)" by simp
  1428   from \<open>sorted ys\<close> show "sorted (map (\<lambda>x. x) ys)" by simp
  1429   from multiset have "\<And>k. length (filter (\<lambda>y. k = y) ys) = length (filter (\<lambda>x. k = x) xs)"
  1429   from multiset have "\<And>k. length (filter (\<lambda>y. k = y) ys) = length (filter (\<lambda>x. k = x) xs)"
  1430     by (rule multiset_of_eq_length_filter)
  1430     by (rule mset_eq_length_filter)
  1431   then have "\<And>k. replicate (length (filter (\<lambda>y. k = y) ys)) k = replicate (length (filter (\<lambda>x. k = x) xs)) k"
  1431   then have "\<And>k. replicate (length (filter (\<lambda>y. k = y) ys)) k = replicate (length (filter (\<lambda>x. k = x) xs)) k"
  1432     by simp
  1432     by simp
  1433   then show "\<And>k. k \<in> set ys \<Longrightarrow> filter (\<lambda>y. k = y) ys = filter (\<lambda>x. k = x) xs"
  1433   then show "\<And>k. k \<in> set ys \<Longrightarrow> filter (\<lambda>y. k = y) ys = filter (\<lambda>x. k = x) xs"
  1434     by (simp add: replicate_length_filter)
  1434     by (simp add: replicate_length_filter)
  1435 qed
  1435 qed
  1437 lemma sort_key_by_quicksort:
  1437 lemma sort_key_by_quicksort:
  1438   "sort_key f xs = sort_key f [x\<leftarrow>xs. f x < f (xs ! (length xs div 2))]
  1438   "sort_key f xs = sort_key f [x\<leftarrow>xs. f x < f (xs ! (length xs div 2))]
  1439     @ [x\<leftarrow>xs. f x = f (xs ! (length xs div 2))]
  1439     @ [x\<leftarrow>xs. f x = f (xs ! (length xs div 2))]
  1440     @ sort_key f [x\<leftarrow>xs. f x > f (xs ! (length xs div 2))]" (is "sort_key f ?lhs = ?rhs")
  1440     @ sort_key f [x\<leftarrow>xs. f x > f (xs ! (length xs div 2))]" (is "sort_key f ?lhs = ?rhs")
  1441 proof (rule properties_for_sort_key)
  1441 proof (rule properties_for_sort_key)
  1442   show "multiset_of ?rhs = multiset_of ?lhs"
  1442   show "mset ?rhs = mset ?lhs"
  1443     by (rule multiset_eqI) (auto simp add: multiset_of_filter)
  1443     by (rule multiset_eqI) (auto simp add: mset_filter)
  1444 next
  1444 next
  1445   show "sorted (map f ?rhs)"
  1445   show "sorted (map f ?rhs)"
  1446     by (auto simp add: sorted_append intro: sorted_map_same)
  1446     by (auto simp add: sorted_append intro: sorted_map_same)
  1447 next
  1447 next
  1448   fix l
  1448   fix l
  1521 
  1521 
  1522 end
  1522 end
  1523 
  1523 
  1524 hide_const (open) part
  1524 hide_const (open) part
  1525 
  1525 
  1526 lemma multiset_of_remdups_le: "multiset_of (remdups xs) \<le># multiset_of xs"
  1526 lemma mset_remdups_le: "mset (remdups xs) \<le># mset xs"
  1527   by (induct xs) (auto intro: subset_mset.order_trans)
  1527   by (induct xs) (auto intro: subset_mset.order_trans)
  1528 
  1528 
  1529 lemma multiset_of_update:
  1529 lemma mset_update:
  1530   "i < length ls \<Longrightarrow> multiset_of (ls[i := v]) = multiset_of ls - {#ls ! i#} + {#v#}"
  1530   "i < length ls \<Longrightarrow> mset (ls[i := v]) = mset ls - {#ls ! i#} + {#v#}"
  1531 proof (induct ls arbitrary: i)
  1531 proof (induct ls arbitrary: i)
  1532   case Nil then show ?case by simp
  1532   case Nil then show ?case by simp
  1533 next
  1533 next
  1534   case (Cons x xs)
  1534   case (Cons x xs)
  1535   show ?case
  1535   show ?case
  1542       apply (subst add.assoc)
  1542       apply (subst add.assoc)
  1543       apply (subst add.commute [of "{#v#}" "{#x#}"])
  1543       apply (subst add.commute [of "{#v#}" "{#x#}"])
  1544       apply (subst add.assoc [symmetric])
  1544       apply (subst add.assoc [symmetric])
  1545       apply simp
  1545       apply simp
  1546       apply (rule mset_le_multiset_union_diff_commute)
  1546       apply (rule mset_le_multiset_union_diff_commute)
  1547       apply (simp add: mset_le_single nth_mem_multiset_of)
  1547       apply (simp add: mset_le_single nth_mem_mset)
  1548       done
  1548       done
  1549   qed
  1549   qed
  1550 qed
  1550 qed
  1551 
  1551 
  1552 lemma multiset_of_swap:
  1552 lemma mset_swap:
  1553   "i < length ls \<Longrightarrow> j < length ls \<Longrightarrow>
  1553   "i < length ls \<Longrightarrow> j < length ls \<Longrightarrow>
  1554     multiset_of (ls[j := ls ! i, i := ls ! j]) = multiset_of ls"
  1554     mset (ls[j := ls ! i, i := ls ! j]) = mset ls"
  1555   by (cases "i = j") (simp_all add: multiset_of_update nth_mem_multiset_of)
  1555   by (cases "i = j") (simp_all add: mset_update nth_mem_mset)
  1556 
  1556 
  1557 
  1557 
  1558 subsection \<open>The multiset order\<close>
  1558 subsection \<open>The multiset order\<close>
  1559 
  1559 
  1560 subsubsection \<open>Well-foundedness\<close>
  1560 subsubsection \<open>Well-foundedness\<close>
  2069 \<close>
  2069 \<close>
  2070 
  2070 
  2071 
  2071 
  2072 subsection \<open>Naive implementation using lists\<close>
  2072 subsection \<open>Naive implementation using lists\<close>
  2073 
  2073 
  2074 code_datatype multiset_of
  2074 code_datatype mset
  2075 
  2075 
  2076 lemma [code]:
  2076 lemma [code]:
  2077   "{#} = multiset_of []"
  2077   "{#} = mset []"
  2078   by simp
  2078   by simp
  2079 
  2079 
  2080 lemma [code]:
  2080 lemma [code]:
  2081   "{#x#} = multiset_of [x]"
  2081   "{#x#} = mset [x]"
  2082   by simp
  2082   by simp
  2083 
  2083 
  2084 lemma union_code [code]:
  2084 lemma union_code [code]:
  2085   "multiset_of xs + multiset_of ys = multiset_of (xs @ ys)"
  2085   "mset xs + mset ys = mset (xs @ ys)"
  2086   by simp
  2086   by simp
  2087 
  2087 
  2088 lemma [code]:
  2088 lemma [code]:
  2089   "image_mset f (multiset_of xs) = multiset_of (map f xs)"
  2089   "image_mset f (mset xs) = mset (map f xs)"
  2090   by (simp add: multiset_of_map)
  2090   by (simp add: mset_map)
  2091 
  2091 
  2092 lemma [code]:
  2092 lemma [code]:
  2093   "filter_mset f (multiset_of xs) = multiset_of (filter f xs)"
  2093   "filter_mset f (mset xs) = mset (filter f xs)"
  2094   by (simp add: multiset_of_filter)
  2094   by (simp add: mset_filter)
  2095 
  2095 
  2096 lemma [code]:
  2096 lemma [code]:
  2097   "multiset_of xs - multiset_of ys = multiset_of (fold remove1 ys xs)"
  2097   "mset xs - mset ys = mset (fold remove1 ys xs)"
  2098   by (rule sym, induct ys arbitrary: xs) (simp_all add: diff_add diff_right_commute)
  2098   by (rule sym, induct ys arbitrary: xs) (simp_all add: diff_add diff_right_commute)
  2099 
  2099 
  2100 lemma [code]:
  2100 lemma [code]:
  2101   "multiset_of xs #\<inter> multiset_of ys =
  2101   "mset xs #\<inter> mset ys =
  2102     multiset_of (snd (fold (\<lambda>x (ys, zs).
  2102     mset (snd (fold (\<lambda>x (ys, zs).
  2103       if x \<in> set ys then (remove1 x ys, x # zs) else (ys, zs)) xs (ys, [])))"
  2103       if x \<in> set ys then (remove1 x ys, x # zs) else (ys, zs)) xs (ys, [])))"
  2104 proof -
  2104 proof -
  2105   have "\<And>zs. multiset_of (snd (fold (\<lambda>x (ys, zs).
  2105   have "\<And>zs. mset (snd (fold (\<lambda>x (ys, zs).
  2106     if x \<in> set ys then (remove1 x ys, x # zs) else (ys, zs)) xs (ys, zs))) =
  2106     if x \<in> set ys then (remove1 x ys, x # zs) else (ys, zs)) xs (ys, zs))) =
  2107       (multiset_of xs #\<inter> multiset_of ys) + multiset_of zs"
  2107       (mset xs #\<inter> mset ys) + mset zs"
  2108     by (induct xs arbitrary: ys)
  2108     by (induct xs arbitrary: ys)
  2109       (auto simp add: mem_set_multiset_eq inter_add_right1 inter_add_right2 ac_simps)
  2109       (auto simp add: mem_set_multiset_eq inter_add_right1 inter_add_right2 ac_simps)
  2110   then show ?thesis by simp
  2110   then show ?thesis by simp
  2111 qed
  2111 qed
  2112 
  2112 
  2113 lemma [code]:
  2113 lemma [code]:
  2114   "multiset_of xs #\<union> multiset_of ys =
  2114   "mset xs #\<union> mset ys =
  2115     multiset_of (split append (fold (\<lambda>x (ys, zs). (remove1 x ys, x # zs)) xs (ys, [])))"
  2115     mset (split append (fold (\<lambda>x (ys, zs). (remove1 x ys, x # zs)) xs (ys, [])))"
  2116 proof -
  2116 proof -
  2117   have "\<And>zs. multiset_of (split append (fold (\<lambda>x (ys, zs). (remove1 x ys, x # zs)) xs (ys, zs))) =
  2117   have "\<And>zs. mset (split append (fold (\<lambda>x (ys, zs). (remove1 x ys, x # zs)) xs (ys, zs))) =
  2118       (multiset_of xs #\<union> multiset_of ys) + multiset_of zs"
  2118       (mset xs #\<union> mset ys) + mset zs"
  2119     by (induct xs arbitrary: ys) (simp_all add: multiset_eq_iff)
  2119     by (induct xs arbitrary: ys) (simp_all add: multiset_eq_iff)
  2120   then show ?thesis by simp
  2120   then show ?thesis by simp
  2121 qed
  2121 qed
  2122 
  2122 
  2123 declare in_multiset_in_set [code_unfold]
  2123 declare in_multiset_in_set [code_unfold]
  2124 
  2124 
  2125 lemma [code]:
  2125 lemma [code]:
  2126   "count (multiset_of xs) x = fold (\<lambda>y. if x = y then Suc else id) xs 0"
  2126   "count (mset xs) x = fold (\<lambda>y. if x = y then Suc else id) xs 0"
  2127 proof -
  2127 proof -
  2128   have "\<And>n. fold (\<lambda>y. if x = y then Suc else id) xs n = count (multiset_of xs) x + n"
  2128   have "\<And>n. fold (\<lambda>y. if x = y then Suc else id) xs n = count (mset xs) x + n"
  2129     by (induct xs) simp_all
  2129     by (induct xs) simp_all
  2130   then show ?thesis by simp
  2130   then show ?thesis by simp
  2131 qed
  2131 qed
  2132 
  2132 
  2133 declare set_mset_multiset_of [code]
  2133 declare set_mset_mset [code]
  2134 
  2134 
  2135 declare sorted_list_of_multiset_multiset_of [code]
  2135 declare sorted_list_of_multiset_mset [code]
  2136 
  2136 
  2137 lemma [code]: -- \<open>not very efficient, but representation-ignorant!\<close>
  2137 lemma [code]: -- \<open>not very efficient, but representation-ignorant!\<close>
  2138   "mset_set A = multiset_of (sorted_list_of_set A)"
  2138   "mset_set A = mset (sorted_list_of_set A)"
  2139   apply (cases "finite A")
  2139   apply (cases "finite A")
  2140   apply simp_all
  2140   apply simp_all
  2141   apply (induct A rule: finite_induct)
  2141   apply (induct A rule: finite_induct)
  2142   apply (simp_all add: add.commute)
  2142   apply (simp_all add: add.commute)
  2143   done
  2143   done
  2144 
  2144 
  2145 declare size_multiset_of [code]
  2145 declare size_mset [code]
  2146 
  2146 
  2147 fun ms_lesseq_impl :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool option" where
  2147 fun ms_lesseq_impl :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool option" where
  2148   "ms_lesseq_impl [] ys = Some (ys \<noteq> [])"
  2148   "ms_lesseq_impl [] ys = Some (ys \<noteq> [])"
  2149 | "ms_lesseq_impl (Cons x xs) ys = (case List.extract (op = x) ys of
  2149 | "ms_lesseq_impl (Cons x xs) ys = (case List.extract (op = x) ys of
  2150      None \<Rightarrow> None
  2150      None \<Rightarrow> None
  2151    | Some (ys1,_,ys2) \<Rightarrow> ms_lesseq_impl xs (ys1 @ ys2))"
  2151    | Some (ys1,_,ys2) \<Rightarrow> ms_lesseq_impl xs (ys1 @ ys2))"
  2152 
  2152 
  2153 lemma ms_lesseq_impl: "(ms_lesseq_impl xs ys = None \<longleftrightarrow> \<not> multiset_of xs \<le># multiset_of ys) \<and>
  2153 lemma ms_lesseq_impl: "(ms_lesseq_impl xs ys = None \<longleftrightarrow> \<not> mset xs \<le># mset ys) \<and>
  2154   (ms_lesseq_impl xs ys = Some True \<longleftrightarrow> multiset_of xs <# multiset_of ys) \<and>
  2154   (ms_lesseq_impl xs ys = Some True \<longleftrightarrow> mset xs <# mset ys) \<and>
  2155   (ms_lesseq_impl xs ys = Some False \<longrightarrow> multiset_of xs = multiset_of ys)"
  2155   (ms_lesseq_impl xs ys = Some False \<longrightarrow> mset xs = mset ys)"
  2156 proof (induct xs arbitrary: ys)
  2156 proof (induct xs arbitrary: ys)
  2157   case (Nil ys)
  2157   case (Nil ys)
  2158   show ?case by (auto simp: mset_less_empty_nonempty)
  2158   show ?case by (auto simp: mset_less_empty_nonempty)
  2159 next
  2159 next
  2160   case (Cons x xs ys)
  2160   case (Cons x xs ys)
  2161   show ?case
  2161   show ?case
  2162   proof (cases "List.extract (op = x) ys")
  2162   proof (cases "List.extract (op = x) ys")
  2163     case None
  2163     case None
  2164     hence x: "x \<notin> set ys" by (simp add: extract_None_iff)
  2164     hence x: "x \<notin> set ys" by (simp add: extract_None_iff)
  2165     {
  2165     {
  2166       assume "multiset_of (x # xs) \<le># multiset_of ys"
  2166       assume "mset (x # xs) \<le># mset ys"
  2167       from set_mset_mono[OF this] x have False by simp
  2167       from set_mset_mono[OF this] x have False by simp
  2168     } note nle = this
  2168     } note nle = this
  2169     moreover
  2169     moreover
  2170     {
  2170     {
  2171       assume "multiset_of (x # xs) <# multiset_of ys"
  2171       assume "mset (x # xs) <# mset ys"
  2172       hence "multiset_of (x # xs) \<le># multiset_of ys" by auto
  2172       hence "mset (x # xs) \<le># mset ys" by auto
  2173       from nle[OF this] have False .
  2173       from nle[OF this] have False .
  2174     }
  2174     }
  2175     ultimately show ?thesis using None by auto
  2175     ultimately show ?thesis using None by auto
  2176   next
  2176   next
  2177     case (Some res)
  2177     case (Some res)
  2178     obtain ys1 y ys2 where res: "res = (ys1,y,ys2)" by (cases res, auto)
  2178     obtain ys1 y ys2 where res: "res = (ys1,y,ys2)" by (cases res, auto)
  2179     note Some = Some[unfolded res]
  2179     note Some = Some[unfolded res]
  2180     from extract_SomeE[OF Some] have "ys = ys1 @ x # ys2" by simp
  2180     from extract_SomeE[OF Some] have "ys = ys1 @ x # ys2" by simp
  2181     hence id: "multiset_of ys = multiset_of (ys1 @ ys2) + {#x#}"
  2181     hence id: "mset ys = mset (ys1 @ ys2) + {#x#}"
  2182       by (auto simp: ac_simps)
  2182       by (auto simp: ac_simps)
  2183     show ?thesis unfolding ms_lesseq_impl.simps
  2183     show ?thesis unfolding ms_lesseq_impl.simps
  2184       unfolding Some option.simps split
  2184       unfolding Some option.simps split
  2185       unfolding id
  2185       unfolding id
  2186       using Cons[of "ys1 @ ys2"]
  2186       using Cons[of "ys1 @ ys2"]
  2187       unfolding subset_mset_def subseteq_mset_def by auto
  2187       unfolding subset_mset_def subseteq_mset_def by auto
  2188   qed
  2188   qed
  2189 qed
  2189 qed
  2190 
  2190 
  2191 lemma [code]: "multiset_of xs \<le># multiset_of ys \<longleftrightarrow> ms_lesseq_impl xs ys \<noteq> None"
  2191 lemma [code]: "mset xs \<le># mset ys \<longleftrightarrow> ms_lesseq_impl xs ys \<noteq> None"
  2192   using ms_lesseq_impl[of xs ys] by (cases "ms_lesseq_impl xs ys", auto)
  2192   using ms_lesseq_impl[of xs ys] by (cases "ms_lesseq_impl xs ys", auto)
  2193 
  2193 
  2194 lemma [code]: "multiset_of xs <# multiset_of ys \<longleftrightarrow> ms_lesseq_impl xs ys = Some True"
  2194 lemma [code]: "mset xs <# mset ys \<longleftrightarrow> ms_lesseq_impl xs ys = Some True"
  2195   using ms_lesseq_impl[of xs ys] by (cases "ms_lesseq_impl xs ys", auto)
  2195   using ms_lesseq_impl[of xs ys] by (cases "ms_lesseq_impl xs ys", auto)
  2196 
  2196 
  2197 instantiation multiset :: (equal) equal
  2197 instantiation multiset :: (equal) equal
  2198 begin
  2198 begin
  2199 
  2199 
  2200 definition
  2200 definition
  2201   [code del]: "HOL.equal A (B :: 'a multiset) \<longleftrightarrow> A = B"
  2201   [code del]: "HOL.equal A (B :: 'a multiset) \<longleftrightarrow> A = B"
  2202 lemma [code]: "HOL.equal (multiset_of xs) (multiset_of ys) \<longleftrightarrow> ms_lesseq_impl xs ys = Some False"
  2202 lemma [code]: "HOL.equal (mset xs) (mset ys) \<longleftrightarrow> ms_lesseq_impl xs ys = Some False"
  2203   unfolding equal_multiset_def
  2203   unfolding equal_multiset_def
  2204   using ms_lesseq_impl[of xs ys] by (cases "ms_lesseq_impl xs ys", auto)
  2204   using ms_lesseq_impl[of xs ys] by (cases "ms_lesseq_impl xs ys", auto)
  2205 
  2205 
  2206 instance
  2206 instance
  2207   by default (simp add: equal_multiset_def)
  2207   by default (simp add: equal_multiset_def)
  2208 end
  2208 end
  2209 
  2209 
  2210 lemma [code]:
  2210 lemma [code]:
  2211   "msetsum (multiset_of xs) = listsum xs"
  2211   "msetsum (mset xs) = listsum xs"
  2212   by (induct xs) (simp_all add: add.commute)
  2212   by (induct xs) (simp_all add: add.commute)
  2213 
  2213 
  2214 lemma [code]:
  2214 lemma [code]:
  2215   "msetprod (multiset_of xs) = fold times xs 1"
  2215   "msetprod (mset xs) = fold times xs 1"
  2216 proof -
  2216 proof -
  2217   have "\<And>x. fold times xs x = msetprod (multiset_of xs) * x"
  2217   have "\<And>x. fold times xs x = msetprod (mset xs) * x"
  2218     by (induct xs) (simp_all add: mult.assoc)
  2218     by (induct xs) (simp_all add: mult.assoc)
  2219   then show ?thesis by simp
  2219   then show ?thesis by simp
  2220 qed
  2220 qed
  2221 
  2221 
  2222 text \<open>
  2222 text \<open>
  2227 text \<open>Quickcheck generators\<close>
  2227 text \<open>Quickcheck generators\<close>
  2228 
  2228 
  2229 definition (in term_syntax)
  2229 definition (in term_syntax)
  2230   msetify :: "'a\<Colon>typerep list \<times> (unit \<Rightarrow> Code_Evaluation.term)
  2230   msetify :: "'a\<Colon>typerep list \<times> (unit \<Rightarrow> Code_Evaluation.term)
  2231     \<Rightarrow> 'a multiset \<times> (unit \<Rightarrow> Code_Evaluation.term)" where
  2231     \<Rightarrow> 'a multiset \<times> (unit \<Rightarrow> Code_Evaluation.term)" where
  2232   [code_unfold]: "msetify xs = Code_Evaluation.valtermify multiset_of {\<cdot>} xs"
  2232   [code_unfold]: "msetify xs = Code_Evaluation.valtermify mset {\<cdot>} xs"
  2233 
  2233 
  2234 notation fcomp (infixl "\<circ>>" 60)
  2234 notation fcomp (infixl "\<circ>>" 60)
  2235 notation scomp (infixl "\<circ>\<rightarrow>" 60)
  2235 notation scomp (infixl "\<circ>\<rightarrow>" 60)
  2236 
  2236 
  2237 instantiation multiset :: (random) random
  2237 instantiation multiset :: (random) random
  2262 
  2262 
  2263 
  2263 
  2264 subsection \<open>BNF setup\<close>
  2264 subsection \<open>BNF setup\<close>
  2265 
  2265 
  2266 definition rel_mset where
  2266 definition rel_mset where
  2267   "rel_mset R X Y \<longleftrightarrow> (\<exists>xs ys. multiset_of xs = X \<and> multiset_of ys = Y \<and> list_all2 R xs ys)"
  2267   "rel_mset R X Y \<longleftrightarrow> (\<exists>xs ys. mset xs = X \<and> mset ys = Y \<and> list_all2 R xs ys)"
  2268 
  2268 
  2269 lemma multiset_of_zip_take_Cons_drop_twice:
  2269 lemma mset_zip_take_Cons_drop_twice:
  2270   assumes "length xs = length ys" "j \<le> length xs"
  2270   assumes "length xs = length ys" "j \<le> length xs"
  2271   shows "multiset_of (zip (take j xs @ x # drop j xs) (take j ys @ y # drop j ys)) =
  2271   shows "mset (zip (take j xs @ x # drop j xs) (take j ys @ y # drop j ys)) =
  2272     multiset_of (zip xs ys) + {#(x, y)#}"
  2272     mset (zip xs ys) + {#(x, y)#}"
  2273 using assms
  2273 using assms
  2274 proof (induct xs ys arbitrary: x y j rule: list_induct2)
  2274 proof (induct xs ys arbitrary: x y j rule: list_induct2)
  2275   case Nil
  2275   case Nil
  2276   thus ?case
  2276   thus ?case
  2277     by simp
  2277     by simp
  2286     case False
  2286     case False
  2287     then obtain k where k: "j = Suc k"
  2287     then obtain k where k: "j = Suc k"
  2288       by (case_tac j) simp
  2288       by (case_tac j) simp
  2289     hence "k \<le> length xs"
  2289     hence "k \<le> length xs"
  2290       using Cons.prems by auto
  2290       using Cons.prems by auto
  2291     hence "multiset_of (zip (take k xs @ x # drop k xs) (take k ys @ y # drop k ys)) =
  2291     hence "mset (zip (take k xs @ x # drop k xs) (take k ys @ y # drop k ys)) =
  2292       multiset_of (zip xs ys) + {#(x, y)#}"
  2292       mset (zip xs ys) + {#(x, y)#}"
  2293       by (rule Cons.hyps(2))
  2293       by (rule Cons.hyps(2))
  2294     thus ?thesis
  2294     thus ?thesis
  2295       unfolding k by (auto simp: add.commute union_lcomm)
  2295       unfolding k by (auto simp: add.commute union_lcomm)
  2296   qed
  2296   qed
  2297 qed
  2297 qed
  2298 
  2298 
  2299 lemma ex_multiset_of_zip_left:
  2299 lemma ex_mset_zip_left:
  2300   assumes "length xs = length ys" "multiset_of xs' = multiset_of xs"
  2300   assumes "length xs = length ys" "mset xs' = mset xs"
  2301   shows "\<exists>ys'. length ys' = length xs' \<and> multiset_of (zip xs' ys') = multiset_of (zip xs ys)"
  2301   shows "\<exists>ys'. length ys' = length xs' \<and> mset (zip xs' ys') = mset (zip xs ys)"
  2302 using assms
  2302 using assms
  2303 proof (induct xs ys arbitrary: xs' rule: list_induct2)
  2303 proof (induct xs ys arbitrary: xs' rule: list_induct2)
  2304   case Nil
  2304   case Nil
  2305   thus ?case
  2305   thus ?case
  2306     by auto
  2306     by auto
  2307 next
  2307 next
  2308   case (Cons x xs y ys xs')
  2308   case (Cons x xs y ys xs')
  2309   obtain j where j_len: "j < length xs'" and nth_j: "xs' ! j = x"
  2309   obtain j where j_len: "j < length xs'" and nth_j: "xs' ! j = x"
  2310     by (metis Cons.prems in_set_conv_nth list.set_intros(1) multiset_of_eq_setD)
  2310     by (metis Cons.prems in_set_conv_nth list.set_intros(1) mset_eq_setD)
  2311 
  2311 
  2312   def xsa \<equiv> "take j xs' @ drop (Suc j) xs'"
  2312   def xsa \<equiv> "take j xs' @ drop (Suc j) xs'"
  2313   have "multiset_of xs' = {#x#} + multiset_of xsa"
  2313   have "mset xs' = {#x#} + mset xsa"
  2314     unfolding xsa_def using j_len nth_j
  2314     unfolding xsa_def using j_len nth_j
  2315     by (metis (no_types) ab_semigroup_add_class.add_ac(1) append_take_drop_id Cons_nth_drop_Suc
  2315     by (metis (no_types) ab_semigroup_add_class.add_ac(1) append_take_drop_id Cons_nth_drop_Suc
  2316       multiset_of.simps(2) union_code add.commute)
  2316       mset.simps(2) union_code add.commute)
  2317   hence ms_x: "multiset_of xsa = multiset_of xs"
  2317   hence ms_x: "mset xsa = mset xs"
  2318     by (metis Cons.prems add.commute add_right_imp_eq multiset_of.simps(2))
  2318     by (metis Cons.prems add.commute add_right_imp_eq mset.simps(2))
  2319   then obtain ysa where
  2319   then obtain ysa where
  2320     len_a: "length ysa = length xsa" and ms_a: "multiset_of (zip xsa ysa) = multiset_of (zip xs ys)"
  2320     len_a: "length ysa = length xsa" and ms_a: "mset (zip xsa ysa) = mset (zip xs ys)"
  2321     using Cons.hyps(2) by blast
  2321     using Cons.hyps(2) by blast
  2322 
  2322 
  2323   def ys' \<equiv> "take j ysa @ y # drop j ysa"
  2323   def ys' \<equiv> "take j ysa @ y # drop j ysa"
  2324   have xs': "xs' = take j xsa @ x # drop j xsa"
  2324   have xs': "xs' = take j xsa @ x # drop j xsa"
  2325     using ms_x j_len nth_j Cons.prems xsa_def
  2325     using ms_x j_len nth_j Cons.prems xsa_def
  2326     by (metis append_eq_append_conv append_take_drop_id diff_Suc_Suc Cons_nth_drop_Suc length_Cons
  2326     by (metis append_eq_append_conv append_take_drop_id diff_Suc_Suc Cons_nth_drop_Suc length_Cons
  2327       length_drop size_multiset_of)
  2327       length_drop size_mset)
  2328   have j_len': "j \<le> length xsa"
  2328   have j_len': "j \<le> length xsa"
  2329     using j_len xs' xsa_def
  2329     using j_len xs' xsa_def
  2330     by (metis add_Suc_right append_take_drop_id length_Cons length_append less_eq_Suc_le not_less)
  2330     by (metis add_Suc_right append_take_drop_id length_Cons length_append less_eq_Suc_le not_less)
  2331   have "length ys' = length xs'"
  2331   have "length ys' = length xs'"
  2332     unfolding ys'_def using Cons.prems len_a ms_x
  2332     unfolding ys'_def using Cons.prems len_a ms_x
  2333     by (metis add_Suc_right append_take_drop_id length_Cons length_append multiset_of_eq_length)
  2333     by (metis add_Suc_right append_take_drop_id length_Cons length_append mset_eq_length)
  2334   moreover have "multiset_of (zip xs' ys') = multiset_of (zip (x # xs) (y # ys))"
  2334   moreover have "mset (zip xs' ys') = mset (zip (x # xs) (y # ys))"
  2335     unfolding xs' ys'_def
  2335     unfolding xs' ys'_def
  2336     by (rule trans[OF multiset_of_zip_take_Cons_drop_twice])
  2336     by (rule trans[OF mset_zip_take_Cons_drop_twice])
  2337       (auto simp: len_a ms_a j_len' add.commute)
  2337       (auto simp: len_a ms_a j_len' add.commute)
  2338   ultimately show ?case
  2338   ultimately show ?case
  2339     by blast
  2339     by blast
  2340 qed
  2340 qed
  2341 
  2341 
  2342 lemma list_all2_reorder_left_invariance:
  2342 lemma list_all2_reorder_left_invariance:
  2343   assumes rel: "list_all2 R xs ys" and ms_x: "multiset_of xs' = multiset_of xs"
  2343   assumes rel: "list_all2 R xs ys" and ms_x: "mset xs' = mset xs"
  2344   shows "\<exists>ys'. list_all2 R xs' ys' \<and> multiset_of ys' = multiset_of ys"
  2344   shows "\<exists>ys'. list_all2 R xs' ys' \<and> mset ys' = mset ys"
  2345 proof -
  2345 proof -
  2346   have len: "length xs = length ys"
  2346   have len: "length xs = length ys"
  2347     using rel list_all2_conv_all_nth by auto
  2347     using rel list_all2_conv_all_nth by auto
  2348   obtain ys' where
  2348   obtain ys' where
  2349     len': "length xs' = length ys'" and ms_xy: "multiset_of (zip xs' ys') = multiset_of (zip xs ys)"
  2349     len': "length xs' = length ys'" and ms_xy: "mset (zip xs' ys') = mset (zip xs ys)"
  2350     using len ms_x by (metis ex_multiset_of_zip_left)
  2350     using len ms_x by (metis ex_mset_zip_left)
  2351   have "list_all2 R xs' ys'"
  2351   have "list_all2 R xs' ys'"
  2352     using assms(1) len' ms_xy unfolding list_all2_iff by (blast dest: multiset_of_eq_setD)
  2352     using assms(1) len' ms_xy unfolding list_all2_iff by (blast dest: mset_eq_setD)
  2353   moreover have "multiset_of ys' = multiset_of ys"
  2353   moreover have "mset ys' = mset ys"
  2354     using len len' ms_xy map_snd_zip multiset_of_map by metis
  2354     using len len' ms_xy map_snd_zip mset_map by metis
  2355   ultimately show ?thesis
  2355   ultimately show ?thesis
  2356     by blast
  2356     by blast
  2357 qed
  2357 qed
  2358 
  2358 
  2359 lemma ex_multiset_of: "\<exists>xs. multiset_of xs = X"
  2359 lemma ex_mset: "\<exists>xs. mset xs = X"
  2360   by (induct X) (simp, metis multiset_of.simps(2))
  2360   by (induct X) (simp, metis mset.simps(2))
  2361 
  2361 
  2362 bnf "'a multiset"
  2362 bnf "'a multiset"
  2363   map: image_mset
  2363   map: image_mset
  2364   sets: set_mset
  2364   sets: set_mset
  2365   bd: natLeq
  2365   bd: natLeq
  2401     (BNF_Def.Grp {x. set_mset x \<subseteq> {(x, y). R x y}} (image_mset fst))\<inverse>\<inverse> OO
  2401     (BNF_Def.Grp {x. set_mset x \<subseteq> {(x, y). R x y}} (image_mset fst))\<inverse>\<inverse> OO
  2402     BNF_Def.Grp {x. set_mset x \<subseteq> {(x, y). R x y}} (image_mset snd)"
  2402     BNF_Def.Grp {x. set_mset x \<subseteq> {(x, y). R x y}} (image_mset snd)"
  2403     unfolding rel_mset_def[abs_def] BNF_Def.Grp_def OO_def
  2403     unfolding rel_mset_def[abs_def] BNF_Def.Grp_def OO_def
  2404     apply (rule ext)+
  2404     apply (rule ext)+
  2405     apply auto
  2405     apply auto
  2406      apply (rule_tac x = "multiset_of (zip xs ys)" in exI; auto)
  2406      apply (rule_tac x = "mset (zip xs ys)" in exI; auto)
  2407         apply (metis list_all2_lengthD map_fst_zip multiset_of_map)
  2407         apply (metis list_all2_lengthD map_fst_zip mset_map)
  2408        apply (auto simp: list_all2_iff)[1]
  2408        apply (auto simp: list_all2_iff)[1]
  2409       apply (metis list_all2_lengthD map_snd_zip multiset_of_map)
  2409       apply (metis list_all2_lengthD map_snd_zip mset_map)
  2410      apply (auto simp: list_all2_iff)[1]
  2410      apply (auto simp: list_all2_iff)[1]
  2411     apply (rename_tac XY)
  2411     apply (rename_tac XY)
  2412     apply (cut_tac X = XY in ex_multiset_of)
  2412     apply (cut_tac X = XY in ex_mset)
  2413     apply (erule exE)
  2413     apply (erule exE)
  2414     apply (rename_tac xys)
  2414     apply (rename_tac xys)
  2415     apply (rule_tac x = "map fst xys" in exI)
  2415     apply (rule_tac x = "map fst xys" in exI)
  2416     apply (auto simp: multiset_of_map)
  2416     apply (auto simp: mset_map)
  2417     apply (rule_tac x = "map snd xys" in exI)
  2417     apply (rule_tac x = "map snd xys" in exI)
  2418     apply (auto simp: multiset_of_map list_all2I subset_eq zip_map_fst_snd)
  2418     apply (auto simp: mset_map list_all2I subset_eq zip_map_fst_snd)
  2419     done
  2419     done
  2420 next
  2420 next
  2421   show "\<And>z. z \<in> set_mset {#} \<Longrightarrow> False"
  2421   show "\<And>z. z \<in> set_mset {#} \<Longrightarrow> False"
  2422     by auto
  2422     by auto
  2423 qed
  2423 qed