src/HOL/Library/Multiset.thy
changeset 74803 825cd198d85c
parent 74634 8f7f626aacaa
child 74804 5749fefd3fa0
equal deleted inserted replaced
74802:b61bd2c12de3 74803:825cd198d85c
     2     Author:     Tobias Nipkow, Markus Wenzel, Lawrence C Paulson, Norbert Voelker
     2     Author:     Tobias Nipkow, Markus Wenzel, Lawrence C Paulson, Norbert Voelker
     3     Author:     Andrei Popescu, TU Muenchen
     3     Author:     Andrei Popescu, TU Muenchen
     4     Author:     Jasmin Blanchette, Inria, LORIA, MPII
     4     Author:     Jasmin Blanchette, Inria, LORIA, MPII
     5     Author:     Dmitriy Traytel, TU Muenchen
     5     Author:     Dmitriy Traytel, TU Muenchen
     6     Author:     Mathias Fleury, MPII
     6     Author:     Mathias Fleury, MPII
       
     7     Author:     Martin Desharnais, MPI-INF Saarbruecken
     7 *)
     8 *)
     8 
     9 
     9 section \<open>(Finite) Multisets\<close>
    10 section \<open>(Finite) Multisets\<close>
    10 
    11 
    11 theory Multiset
    12 theory Multiset
  3061 
  3062 
  3062 text \<open>
  3063 text \<open>
  3063   Predicate variants of \<open>mult\<close> and the reflexive closure of \<open>mult\<close>, which are
  3064   Predicate variants of \<open>mult\<close> and the reflexive closure of \<open>mult\<close>, which are
  3064   executable whenever the given predicate \<open>P\<close> is. Together with the standard
  3065   executable whenever the given predicate \<open>P\<close> is. Together with the standard
  3065   code equations for \<open>(\<inter>#\<close>) and \<open>(-\<close>) this should yield quadratic
  3066   code equations for \<open>(\<inter>#\<close>) and \<open>(-\<close>) this should yield quadratic
  3066   (with respect to calls to \<open>P\<close>) implementations of \<open>multp\<close> and \<open>multeqp\<close>.
  3067   (with respect to calls to \<open>P\<close>) implementations of \<open>multp_code\<close> and \<open>multeqp_code\<close>.
  3067 \<close>
  3068 \<close>
  3068 
  3069 
  3069 definition multp :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset \<Rightarrow> bool" where
  3070 definition multp_code :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset \<Rightarrow> bool" where
  3070   "multp P N M =
  3071   "multp_code P N M =
  3071     (let Z = M \<inter># N; X = M - Z in
  3072     (let Z = M \<inter># N; X = M - Z in
  3072     X \<noteq> {#} \<and> (let Y = N - Z in (\<forall>y \<in> set_mset Y. \<exists>x \<in> set_mset X. P y x)))"
  3073     X \<noteq> {#} \<and> (let Y = N - Z in (\<forall>y \<in> set_mset Y. \<exists>x \<in> set_mset X. P y x)))"
  3073 
  3074 
  3074 definition multeqp :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset \<Rightarrow> bool" where
  3075 definition multeqp_code :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset \<Rightarrow> bool" where
  3075   "multeqp P N M =
  3076   "multeqp_code P N M =
  3076     (let Z = M \<inter># N; X = M - Z; Y = N - Z in
  3077     (let Z = M \<inter># N; X = M - Z; Y = N - Z in
  3077     (\<forall>y \<in> set_mset Y. \<exists>x \<in> set_mset X. P y x))"
  3078     (\<forall>y \<in> set_mset Y. \<exists>x \<in> set_mset X. P y x))"
  3078 
  3079 
  3079 lemma multp_iff:
  3080 lemma multp_code_iff:
  3080   assumes "irrefl R" and "trans R" and [simp]: "\<And>x y. P x y \<longleftrightarrow> (x, y) \<in> R"
  3081   assumes "irrefl R" and "trans R" and [simp]: "\<And>x y. P x y \<longleftrightarrow> (x, y) \<in> R"
  3081   shows "multp P N M \<longleftrightarrow> (N, M) \<in> mult R" (is "?L \<longleftrightarrow> ?R")
  3082   shows "multp_code P N M \<longleftrightarrow> (N, M) \<in> mult R" (is "?L \<longleftrightarrow> ?R")
  3082 proof -
  3083 proof -
  3083   have *: "M \<inter># N + (N - M \<inter># N) = N" "M \<inter># N + (M - M \<inter># N) = M"
  3084   have *: "M \<inter># N + (N - M \<inter># N) = N" "M \<inter># N + (M - M \<inter># N) = M"
  3084     "(M - M \<inter># N) \<inter># (N - M \<inter># N) = {#}" by (auto simp flip: count_inject)
  3085     "(M - M \<inter># N) \<inter># (N - M \<inter># N) = {#}" by (auto simp flip: count_inject)
  3085   show ?thesis
  3086   show ?thesis
  3086   proof
  3087   proof
  3087     assume ?L thus ?R
  3088     assume ?L thus ?R
  3088       using one_step_implies_mult[of "M - M \<inter># N" "N - M \<inter># N" R "M \<inter># N"] *
  3089       using one_step_implies_mult[of "M - M \<inter># N" "N - M \<inter># N" R "M \<inter># N"] *
  3089       by (auto simp: multp_def Let_def)
  3090       by (auto simp: multp_code_def Let_def)
  3090   next
  3091   next
  3091     { fix I J K :: "'a multiset" assume "(I + J) \<inter># (I + K) = {#}"
  3092     { fix I J K :: "'a multiset" assume "(I + J) \<inter># (I + K) = {#}"
  3092       then have "I = {#}" by (metis inter_union_distrib_right union_eq_empty)
  3093       then have "I = {#}" by (metis inter_union_distrib_right union_eq_empty)
  3093     } note [dest!] = this
  3094     } note [dest!] = this
  3094     assume ?R thus ?L
  3095     assume ?R thus ?L
  3095       using mult_implies_one_step[OF assms(2), of "N - M \<inter># N" "M - M \<inter># N"]
  3096       using mult_implies_one_step[OF assms(2), of "N - M \<inter># N" "M - M \<inter># N"]
  3096         mult_cancel_max[OF assms(2,1), of "N" "M"] * by (auto simp: multp_def)
  3097         mult_cancel_max[OF assms(2,1), of "N" "M"] * by (auto simp: multp_code_def)
  3097   qed
  3098   qed
  3098 qed
  3099 qed
  3099 
  3100 
  3100 lemma multeqp_iff:
  3101 lemma multeqp_code_iff:
  3101   assumes "irrefl R" and "trans R" and "\<And>x y. P x y \<longleftrightarrow> (x, y) \<in> R"
  3102   assumes "irrefl R" and "trans R" and "\<And>x y. P x y \<longleftrightarrow> (x, y) \<in> R"
  3102   shows "multeqp P N M \<longleftrightarrow> (N, M) \<in> (mult R)\<^sup>="
  3103   shows "multeqp_code P N M \<longleftrightarrow> (N, M) \<in> (mult R)\<^sup>="
  3103 proof -
  3104 proof -
  3104   { assume "N \<noteq> M" "M - M \<inter># N = {#}"
  3105   { assume "N \<noteq> M" "M - M \<inter># N = {#}"
  3105     then obtain y where "count N y \<noteq> count M y" by (auto simp flip: count_inject)
  3106     then obtain y where "count N y \<noteq> count M y" by (auto simp flip: count_inject)
  3106     then have "\<exists>y. count M y < count N y" using \<open>M - M \<inter># N = {#}\<close>
  3107     then have "\<exists>y. count M y < count N y" using \<open>M - M \<inter># N = {#}\<close>
  3107       by (auto simp flip: count_inject dest!: le_neq_implies_less fun_cong[of _ _ y])
  3108       by (auto simp flip: count_inject dest!: le_neq_implies_less fun_cong[of _ _ y])
  3108   }
  3109   }
  3109   then have "multeqp P N M \<longleftrightarrow> multp P N M \<or> N = M"
  3110   then have "multeqp_code P N M \<longleftrightarrow> multp_code P N M \<or> N = M"
  3110     by (auto simp: multeqp_def multp_def Let_def in_diff_count)
  3111     by (auto simp: multeqp_code_def multp_code_def Let_def in_diff_count)
  3111   thus ?thesis using multp_iff[OF assms] by simp
  3112   thus ?thesis using multp_code_iff[OF assms] by simp
  3112 qed
  3113 qed
  3113 
  3114 
  3114 
  3115 
  3115 subsubsection \<open>Partial-order properties\<close>
  3116 subsubsection \<open>Partial-order properties\<close>
  3116 
  3117