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 |