src/HOL/Library/Multiset.thy
changeset 73706 4b1386b2c23e
parent 73594 5c4a09c4bc9c
child 73832 9db620f007fa
equal deleted inserted replaced
73705:ac07f6be27ea 73706:4b1386b2c23e
  1921   assumes "mset xs = mset ys"
  1921   assumes "mset xs = mset ys"
  1922   shows "length (filter (\<lambda>x. z = x) xs) = length (filter (\<lambda>y. z = y) ys)"
  1922   shows "length (filter (\<lambda>x. z = x) xs) = length (filter (\<lambda>y. z = y) ys)"
  1923   using assms by (metis count_mset)
  1923   using assms by (metis count_mset)
  1924 
  1924 
  1925 lemma fold_multiset_equiv:
  1925 lemma fold_multiset_equiv:
  1926   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"
  1926   \<open>List.fold f xs = List.fold f ys\<close>
  1927     and equiv: "mset xs = mset ys"
  1927     if f: \<open>\<And>x y. x \<in> set xs \<Longrightarrow> y \<in> set xs \<Longrightarrow> f x \<circ> f y = f y \<circ> f x\<close>
  1928   shows "List.fold f xs = List.fold f ys"
  1928     and \<open>mset xs = mset ys\<close>
  1929   using f equiv [symmetric]
  1929 using f \<open>mset xs = mset ys\<close> [symmetric] proof (induction xs arbitrary: ys)
  1930 proof (induct xs arbitrary: ys)
       
  1931   case Nil
  1930   case Nil
  1932   then show ?case by simp
  1931   then show ?case by simp
  1933 next
  1932 next
  1934   case (Cons x xs)
  1933   case (Cons x xs)
  1935   then have *: "set ys = set (x # xs)"
  1934   then have *: \<open>set ys = set (x # xs)\<close>
  1936     by (blast dest: mset_eq_setD)
  1935     by (blast dest: mset_eq_setD)
  1937   have "\<And>x y. x \<in> set ys \<Longrightarrow> y \<in> set ys \<Longrightarrow> f x \<circ> f y = f y \<circ> f x"
  1936   have \<open>\<And>x y. x \<in> set ys \<Longrightarrow> y \<in> set ys \<Longrightarrow> f x \<circ> f y = f y \<circ> f x\<close>
  1938     by (rule Cons.prems(1)) (simp_all add: *)
  1937     by (rule Cons.prems(1)) (simp_all add: *)
  1939   moreover from * have "x \<in> set ys"
  1938   moreover from * have \<open>x \<in> set ys\<close>
  1940     by simp
  1939     by simp
  1941   ultimately have "List.fold f ys = List.fold f (remove1 x ys) \<circ> f x"
  1940   ultimately have \<open>List.fold f ys = List.fold f (remove1 x ys) \<circ> f x\<close>
  1942     by (fact fold_remove1_split)
  1941     by (fact fold_remove1_split)
  1943   moreover from Cons.prems have "List.fold f xs = List.fold f (remove1 x ys)"
  1942   moreover from Cons.prems have \<open>List.fold f xs = List.fold f (remove1 x ys)\<close>
  1944     by (auto intro: Cons.hyps)
  1943     by (auto intro: Cons.IH)
  1945   ultimately show ?case by simp
  1944   ultimately show ?case
       
  1945     by simp
       
  1946 qed
       
  1947 
       
  1948 lemma fold_permuted_eq:
       
  1949   \<open>List.fold (\<odot>) xs z = List.fold (\<odot>) ys z\<close>
       
  1950     if \<open>mset xs = mset ys\<close>
       
  1951     and \<open>P z\<close> and P: \<open>\<And>x z. x \<in> set xs \<Longrightarrow> P z \<Longrightarrow> P (x \<odot> z)\<close>
       
  1952     and f: \<open>\<And>x y z. x \<in> set xs \<Longrightarrow> y \<in> set xs \<Longrightarrow> P z \<Longrightarrow> x \<odot> (y \<odot> z) = y \<odot> (x \<odot> z)\<close>
       
  1953   for f (infixl \<open>\<odot>\<close> 70)
       
  1954 using \<open>P z\<close> P f \<open>mset xs = mset ys\<close> [symmetric] proof (induction xs arbitrary: ys z)
       
  1955   case Nil
       
  1956   then show ?case by simp
       
  1957 next
       
  1958   case (Cons x xs)
       
  1959   then have *: \<open>set ys = set (x # xs)\<close>
       
  1960     by (blast dest: mset_eq_setD)
       
  1961   have \<open>P z\<close>
       
  1962     by (fact Cons.prems(1))
       
  1963   moreover have \<open>\<And>x z. x \<in> set ys \<Longrightarrow> P z \<Longrightarrow> P (x \<odot> z)\<close>
       
  1964     by (rule Cons.prems(2)) (simp_all add: *)
       
  1965   moreover have \<open>\<And>x y z. x \<in> set ys \<Longrightarrow> y \<in> set ys \<Longrightarrow> P z \<Longrightarrow> x \<odot> (y \<odot> z) = y \<odot> (x \<odot> z)\<close>
       
  1966     by (rule Cons.prems(3)) (simp_all add: *)
       
  1967   moreover from * have \<open>x \<in> set ys\<close>
       
  1968     by simp
       
  1969   ultimately have \<open>fold (\<odot>) ys z = fold (\<odot>) (remove1 x ys) (x \<odot> z)\<close>
       
  1970     by (induction ys arbitrary: z) auto
       
  1971   moreover from Cons.prems have \<open>fold (\<odot>) xs (x \<odot> z) = fold (\<odot>) (remove1 x ys) (x \<odot> z)\<close>
       
  1972     by (auto intro: Cons.IH)
       
  1973   ultimately show ?case
       
  1974     by simp
  1946 qed
  1975 qed
  1947 
  1976 
  1948 lemma mset_shuffles: "zs \<in> shuffles xs ys \<Longrightarrow> mset zs = mset xs + mset ys"
  1977 lemma mset_shuffles: "zs \<in> shuffles xs ys \<Longrightarrow> mset zs = mset xs + mset ys"
  1949   by (induction xs ys arbitrary: zs rule: shuffles.induct) auto
  1978   by (induction xs ys arbitrary: zs rule: shuffles.induct) auto
  1950 
  1979