src/ZF/Induct/Multiset.thy
changeset 76213 e44d86131648
parent 69593 3dda49e08b9d
child 76214 0c18df79b1c8
equal deleted inserted replaced
76212:f2094906e491 76213:e44d86131648
    12 begin
    12 begin
    13 
    13 
    14 abbreviation (input)
    14 abbreviation (input)
    15   \<comment> \<open>Short cut for multiset space\<close>
    15   \<comment> \<open>Short cut for multiset space\<close>
    16   Mult :: "i=>i" where
    16   Mult :: "i=>i" where
    17   "Mult(A) == A -||> nat-{0}"
    17   "Mult(A) \<equiv> A -||> nat-{0}"
    18 
    18 
    19 definition
    19 definition
    20   (* This is the original "restrict" from ZF.thy.
    20   (* This is the original "restrict" from ZF.thy.
    21      Restricts the function f to the domain A
    21      Restricts the function f to the domain A
    22      FIXME: adapt Multiset to the new "restrict". *)
    22      FIXME: adapt Multiset to the new "restrict". *)
    23   funrestrict :: "[i,i] => i"  where
    23   funrestrict :: "[i,i] => i"  where
    24   "funrestrict(f,A) == \<lambda>x \<in> A. f`x"
    24   "funrestrict(f,A) \<equiv> \<lambda>x \<in> A. f`x"
    25 
    25 
    26 definition
    26 definition
    27   (* M is a multiset *)
    27   (* M is a multiset *)
    28   multiset :: "i => o"  where
    28   multiset :: "i => o"  where
    29   "multiset(M) == \<exists>A. M \<in> A -> nat-{0} & Finite(A)"
    29   "multiset(M) \<equiv> \<exists>A. M \<in> A -> nat-{0} & Finite(A)"
    30 
    30 
    31 definition
    31 definition
    32   mset_of :: "i=>i"  where
    32   mset_of :: "i=>i"  where
    33   "mset_of(M) == domain(M)"
    33   "mset_of(M) \<equiv> domain(M)"
    34 
    34 
    35 definition
    35 definition
    36   munion    :: "[i, i] => i" (infixl \<open>+#\<close> 65)  where
    36   munion    :: "[i, i] => i" (infixl \<open>+#\<close> 65)  where
    37   "M +# N == \<lambda>x \<in> mset_of(M) \<union> mset_of(N).
    37   "M +# N \<equiv> \<lambda>x \<in> mset_of(M) \<union> mset_of(N).
    38      if x \<in> mset_of(M) \<inter> mset_of(N) then  (M`x) #+ (N`x)
    38      if x \<in> mset_of(M) \<inter> mset_of(N) then  (M`x) #+ (N`x)
    39      else (if x \<in> mset_of(M) then M`x else N`x)"
    39      else (if x \<in> mset_of(M) then M`x else N`x)"
    40 
    40 
    41 definition
    41 definition
    42   (*convert a function to a multiset by eliminating 0*)
    42   (*convert a function to a multiset by eliminating 0*)
    43   normalize :: "i => i"  where
    43   normalize :: "i => i"  where
    44   "normalize(f) ==
    44   "normalize(f) \<equiv>
    45        if (\<exists>A. f \<in> A -> nat & Finite(A)) then
    45        if (\<exists>A. f \<in> A -> nat & Finite(A)) then
    46             funrestrict(f, {x \<in> mset_of(f). 0 < f`x})
    46             funrestrict(f, {x \<in> mset_of(f). 0 < f`x})
    47        else 0"
    47        else 0"
    48 
    48 
    49 definition
    49 definition
    50   mdiff  :: "[i, i] => i" (infixl \<open>-#\<close> 65)  where
    50   mdiff  :: "[i, i] => i" (infixl \<open>-#\<close> 65)  where
    51   "M -# N ==  normalize(\<lambda>x \<in> mset_of(M).
    51   "M -# N \<equiv>  normalize(\<lambda>x \<in> mset_of(M).
    52                         if x \<in> mset_of(N) then M`x #- N`x else M`x)"
    52                         if x \<in> mset_of(N) then M`x #- N`x else M`x)"
    53 
    53 
    54 definition
    54 definition
    55   (* set of elements of a multiset *)
    55   (* set of elements of a multiset *)
    56   msingle :: "i => i"    (\<open>{#_#}\<close>)  where
    56   msingle :: "i => i"    (\<open>{#_#}\<close>)  where
    57   "{#a#} == {<a, 1>}"
    57   "{#a#} \<equiv> {<a, 1>}"
    58 
    58 
    59 definition
    59 definition
    60   MCollect :: "[i, i=>o] => i"  (*comprehension*)  where
    60   MCollect :: "[i, i=>o] => i"  (*comprehension*)  where
    61   "MCollect(M, P) == funrestrict(M, {x \<in> mset_of(M). P(x)})"
    61   "MCollect(M, P) \<equiv> funrestrict(M, {x \<in> mset_of(M). P(x)})"
    62 
    62 
    63 definition
    63 definition
    64   (* Counts the number of occurrences of an element in a multiset *)
    64   (* Counts the number of occurrences of an element in a multiset *)
    65   mcount :: "[i, i] => i"  where
    65   mcount :: "[i, i] => i"  where
    66   "mcount(M, a) == if a \<in> mset_of(M) then  M`a else 0"
    66   "mcount(M, a) \<equiv> if a \<in> mset_of(M) then  M`a else 0"
    67 
    67 
    68 definition
    68 definition
    69   msize :: "i => i"  where
    69   msize :: "i => i"  where
    70   "msize(M) == setsum(%a. $# mcount(M,a), mset_of(M))"
    70   "msize(M) \<equiv> setsum(%a. $# mcount(M,a), mset_of(M))"
    71 
    71 
    72 abbreviation
    72 abbreviation
    73   melem :: "[i,i] => o"    (\<open>(_/ :# _)\<close> [50, 51] 50)  where
    73   melem :: "[i,i] => o"    (\<open>(_/ :# _)\<close> [50, 51] 50)  where
    74   "a :# M == a \<in> mset_of(M)"
    74   "a :# M \<equiv> a \<in> mset_of(M)"
    75 
    75 
    76 syntax
    76 syntax
    77   "_MColl" :: "[pttrn, i, o] => i" (\<open>(1{# _ \<in> _./ _#})\<close>)
    77   "_MColl" :: "[pttrn, i, o] => i" (\<open>(1{# _ \<in> _./ _#})\<close>)
    78 translations
    78 translations
    79   "{#x \<in> M. P#}" == "CONST MCollect(M, \<lambda>x. P)"
    79   "{#x \<in> M. P#}" == "CONST MCollect(M, \<lambda>x. P)"
    82 
    82 
    83 definition
    83 definition
    84    (* multirel1 has to be a set (not a predicate) so that we can form
    84    (* multirel1 has to be a set (not a predicate) so that we can form
    85       its transitive closure and reason about wf(.) and acc(.) *)
    85       its transitive closure and reason about wf(.) and acc(.) *)
    86   multirel1 :: "[i,i]=>i"  where
    86   multirel1 :: "[i,i]=>i"  where
    87   "multirel1(A, r) ==
    87   "multirel1(A, r) \<equiv>
    88      {<M, N> \<in> Mult(A)*Mult(A).
    88      {<M, N> \<in> Mult(A)*Mult(A).
    89       \<exists>a \<in> A. \<exists>M0 \<in> Mult(A). \<exists>K \<in> Mult(A).
    89       \<exists>a \<in> A. \<exists>M0 \<in> Mult(A). \<exists>K \<in> Mult(A).
    90       N=M0 +# {#a#} & M=M0 +# K & (\<forall>b \<in> mset_of(K). <b,a> \<in> r)}"
    90       N=M0 +# {#a#} & M=M0 +# K & (\<forall>b \<in> mset_of(K). <b,a> \<in> r)}"
    91 
    91 
    92 definition
    92 definition
    93   multirel :: "[i, i] => i"  where
    93   multirel :: "[i, i] => i"  where
    94   "multirel(A, r) == multirel1(A, r)^+"
    94   "multirel(A, r) \<equiv> multirel1(A, r)^+"
    95 
    95 
    96   (* ordinal multiset orderings *)
    96   (* ordinal multiset orderings *)
    97 
    97 
    98 definition
    98 definition
    99   omultiset :: "i => o"  where
    99   omultiset :: "i => o"  where
   100   "omultiset(M) == \<exists>i. Ord(i) & M \<in> Mult(field(Memrel(i)))"
   100   "omultiset(M) \<equiv> \<exists>i. Ord(i) & M \<in> Mult(field(Memrel(i)))"
   101 
   101 
   102 definition
   102 definition
   103   mless :: "[i, i] => o" (infixl \<open><#\<close> 50)  where
   103   mless :: "[i, i] => o" (infixl \<open><#\<close> 50)  where
   104   "M <# N ==  \<exists>i. Ord(i) & <M, N> \<in> multirel(field(Memrel(i)), Memrel(i))"
   104   "M <# N \<equiv>  \<exists>i. Ord(i) & <M, N> \<in> multirel(field(Memrel(i)), Memrel(i))"
   105 
   105 
   106 definition
   106 definition
   107   mle  :: "[i, i] => o"  (infixl \<open><#=\<close> 50)  where
   107   mle  :: "[i, i] => o"  (infixl \<open><#=\<close> 50)  where
   108   "M <#= N == (omultiset(M) & M = N) | M <# N"
   108   "M <#= N \<equiv> (omultiset(M) & M = N) | M <# N"
   109 
   109 
   110 
   110 
   111 subsection\<open>Properties of the original "restrict" from ZF.thy\<close>
   111 subsection\<open>Properties of the original "restrict" from ZF.thy\<close>
   112 
   112 
   113 lemma funrestrict_subset: "[| f \<in> Pi(C,B);  A\<subseteq>C |] ==> funrestrict(f,A) \<subseteq> f"
   113 lemma funrestrict_subset: "\<lbrakk>f \<in> Pi(C,B);  A\<subseteq>C\<rbrakk> \<Longrightarrow> funrestrict(f,A) \<subseteq> f"
   114 by (auto simp add: funrestrict_def lam_def intro: apply_Pair)
   114 by (auto simp add: funrestrict_def lam_def intro: apply_Pair)
   115 
   115 
   116 lemma funrestrict_type:
   116 lemma funrestrict_type:
   117     "[| !!x. x \<in> A ==> f`x \<in> B(x) |] ==> funrestrict(f,A) \<in> Pi(A,B)"
   117     "\<lbrakk>\<And>x. x \<in> A \<Longrightarrow> f`x \<in> B(x)\<rbrakk> \<Longrightarrow> funrestrict(f,A) \<in> Pi(A,B)"
   118 by (simp add: funrestrict_def lam_type)
   118 by (simp add: funrestrict_def lam_type)
   119 
   119 
   120 lemma funrestrict_type2: "[| f \<in> Pi(C,B);  A\<subseteq>C |] ==> funrestrict(f,A) \<in> Pi(A,B)"
   120 lemma funrestrict_type2: "\<lbrakk>f \<in> Pi(C,B);  A\<subseteq>C\<rbrakk> \<Longrightarrow> funrestrict(f,A) \<in> Pi(A,B)"
   121 by (blast intro: apply_type funrestrict_type)
   121 by (blast intro: apply_type funrestrict_type)
   122 
   122 
   123 lemma funrestrict [simp]: "a \<in> A ==> funrestrict(f,A) ` a = f`a"
   123 lemma funrestrict [simp]: "a \<in> A \<Longrightarrow> funrestrict(f,A) ` a = f`a"
   124 by (simp add: funrestrict_def)
   124 by (simp add: funrestrict_def)
   125 
   125 
   126 lemma funrestrict_empty [simp]: "funrestrict(f,0) = 0"
   126 lemma funrestrict_empty [simp]: "funrestrict(f,0) = 0"
   127 by (simp add: funrestrict_def)
   127 by (simp add: funrestrict_def)
   128 
   128 
   129 lemma domain_funrestrict [simp]: "domain(funrestrict(f,C)) = C"
   129 lemma domain_funrestrict [simp]: "domain(funrestrict(f,C)) = C"
   130 by (auto simp add: funrestrict_def lam_def)
   130 by (auto simp add: funrestrict_def lam_def)
   131 
   131 
   132 lemma fun_cons_funrestrict_eq:
   132 lemma fun_cons_funrestrict_eq:
   133      "f \<in> cons(a, b) -> B ==> f = cons(<a, f ` a>, funrestrict(f, b))"
   133      "f \<in> cons(a, b) -> B \<Longrightarrow> f = cons(<a, f ` a>, funrestrict(f, b))"
   134 apply (rule equalityI)
   134 apply (rule equalityI)
   135 prefer 2 apply (blast intro: apply_Pair funrestrict_subset [THEN subsetD])
   135 prefer 2 apply (blast intro: apply_Pair funrestrict_subset [THEN subsetD])
   136 apply (auto dest!: Pi_memberD simp add: funrestrict_def lam_def)
   136 apply (auto dest!: Pi_memberD simp add: funrestrict_def lam_def)
   137 done
   137 done
   138 
   138 
   149             dest: apply_type Diff_subset [THEN Pi_mono, THEN subsetD]
   149             dest: apply_type Diff_subset [THEN Pi_mono, THEN subsetD]
   150             simp add: range_of_fun apply_iff)
   150             simp add: range_of_fun apply_iff)
   151 done
   151 done
   152 
   152 
   153 (** The multiset space  **)
   153 (** The multiset space  **)
   154 lemma multiset_into_Mult: "[| multiset(M); mset_of(M)\<subseteq>A |] ==> M \<in> Mult(A)"
   154 lemma multiset_into_Mult: "\<lbrakk>multiset(M); mset_of(M)\<subseteq>A\<rbrakk> \<Longrightarrow> M \<in> Mult(A)"
   155 apply (simp add: multiset_def)
   155 apply (simp add: multiset_def)
   156 apply (auto simp add: multiset_fun_iff mset_of_def)
   156 apply (auto simp add: multiset_fun_iff mset_of_def)
   157 apply (rule_tac B1 = "nat-{0}" in FiniteFun_mono [THEN subsetD], simp_all)
   157 apply (rule_tac B1 = "nat-{0}" in FiniteFun_mono [THEN subsetD], simp_all)
   158 apply (rule Finite_into_Fin [THEN [2] Fin_mono [THEN subsetD], THEN fun_FiniteFunI])
   158 apply (rule Finite_into_Fin [THEN [2] Fin_mono [THEN subsetD], THEN fun_FiniteFunI])
   159 apply (simp_all (no_asm_simp) add: multiset_fun_iff)
   159 apply (simp_all (no_asm_simp) add: multiset_fun_iff)
   160 done
   160 done
   161 
   161 
   162 lemma Mult_into_multiset: "M \<in> Mult(A) ==> multiset(M) & mset_of(M)\<subseteq>A"
   162 lemma Mult_into_multiset: "M \<in> Mult(A) \<Longrightarrow> multiset(M) & mset_of(M)\<subseteq>A"
   163 apply (simp add: multiset_def mset_of_def)
   163 apply (simp add: multiset_def mset_of_def)
   164 apply (frule FiniteFun_is_fun)
   164 apply (frule FiniteFun_is_fun)
   165 apply (drule FiniteFun_domain_Fin)
   165 apply (drule FiniteFun_domain_Fin)
   166 apply (frule FinD, clarify)
   166 apply (frule FinD, clarify)
   167 apply (rule_tac x = "domain (M) " in exI)
   167 apply (rule_tac x = "domain (M) " in exI)
   183 by (auto intro: FiniteFun.intros simp add: multiset_iff_Mult_mset_of)
   183 by (auto intro: FiniteFun.intros simp add: multiset_iff_Mult_mset_of)
   184 
   184 
   185 
   185 
   186 text\<open>The \<^term>\<open>mset_of\<close> operator\<close>
   186 text\<open>The \<^term>\<open>mset_of\<close> operator\<close>
   187 
   187 
   188 lemma multiset_set_of_Finite [simp]: "multiset(M) ==> Finite(mset_of(M))"
   188 lemma multiset_set_of_Finite [simp]: "multiset(M) \<Longrightarrow> Finite(mset_of(M))"
   189 by (simp add: multiset_def mset_of_def, auto)
   189 by (simp add: multiset_def mset_of_def, auto)
   190 
   190 
   191 lemma mset_of_0 [iff]: "mset_of(0) = 0"
   191 lemma mset_of_0 [iff]: "mset_of(0) = 0"
   192 by (simp add: mset_of_def)
   192 by (simp add: mset_of_def)
   193 
   193 
   194 lemma mset_is_0_iff: "multiset(M) ==> mset_of(M)=0 \<longleftrightarrow> M=0"
   194 lemma mset_is_0_iff: "multiset(M) \<Longrightarrow> mset_of(M)=0 \<longleftrightarrow> M=0"
   195 by (auto simp add: multiset_def mset_of_def)
   195 by (auto simp add: multiset_def mset_of_def)
   196 
   196 
   197 lemma mset_of_single [iff]: "mset_of({#a#}) = {a}"
   197 lemma mset_of_single [iff]: "mset_of({#a#}) = {a}"
   198 by (simp add: msingle_def mset_of_def)
   198 by (simp add: msingle_def mset_of_def)
   199 
   199 
   200 lemma mset_of_union [iff]: "mset_of(M +# N) = mset_of(M) \<union> mset_of(N)"
   200 lemma mset_of_union [iff]: "mset_of(M +# N) = mset_of(M) \<union> mset_of(N)"
   201 by (simp add: mset_of_def munion_def)
   201 by (simp add: mset_of_def munion_def)
   202 
   202 
   203 lemma mset_of_diff [simp]: "mset_of(M)\<subseteq>A ==> mset_of(M -# N) \<subseteq> A"
   203 lemma mset_of_diff [simp]: "mset_of(M)\<subseteq>A \<Longrightarrow> mset_of(M -# N) \<subseteq> A"
   204 by (auto simp add: mdiff_def multiset_def normalize_def mset_of_def)
   204 by (auto simp add: mdiff_def multiset_def normalize_def mset_of_def)
   205 
   205 
   206 (* msingle *)
   206 (* msingle *)
   207 
   207 
   208 lemma msingle_not_0 [iff]: "{#a#} \<noteq> 0 & 0 \<noteq> {#a#}"
   208 lemma msingle_not_0 [iff]: "{#a#} \<noteq> 0 & 0 \<noteq> {#a#}"
   228 apply (drule_tac x = "{x \<in> domain (f) . 0 < f ` x}" in spec)
   228 apply (drule_tac x = "{x \<in> domain (f) . 0 < f ` x}" in spec)
   229 apply auto
   229 apply auto
   230 apply (auto  intro!: lam_type simp add: Collect_Finite)
   230 apply (auto  intro!: lam_type simp add: Collect_Finite)
   231 done
   231 done
   232 
   232 
   233 lemma normalize_multiset [simp]: "multiset(M) ==> normalize(M) = M"
   233 lemma normalize_multiset [simp]: "multiset(M) \<Longrightarrow> normalize(M) = M"
   234 by (auto simp add: multiset_def normalize_def mset_of_def funrestrict_def multiset_fun_iff)
   234 by (auto simp add: multiset_def normalize_def mset_of_def funrestrict_def multiset_fun_iff)
   235 
   235 
   236 lemma multiset_normalize [simp]: "multiset(normalize(f))"
   236 lemma multiset_normalize [simp]: "multiset(normalize(f))"
   237 apply (simp add: normalize_def)
   237 apply (simp add: normalize_def)
   238 apply (simp add: normalize_def mset_of_def multiset_def, auto)
   238 apply (simp add: normalize_def mset_of_def multiset_def, auto)
   242 
   242 
   243 (** Typechecking rules for union and difference of multisets **)
   243 (** Typechecking rules for union and difference of multisets **)
   244 
   244 
   245 (* union *)
   245 (* union *)
   246 
   246 
   247 lemma munion_multiset [simp]: "[| multiset(M); multiset(N) |] ==> multiset(M +# N)"
   247 lemma munion_multiset [simp]: "\<lbrakk>multiset(M); multiset(N)\<rbrakk> \<Longrightarrow> multiset(M +# N)"
   248 apply (unfold multiset_def munion_def mset_of_def, auto)
   248 apply (unfold multiset_def munion_def mset_of_def, auto)
   249 apply (rule_tac x = "A \<union> Aa" in exI)
   249 apply (rule_tac x = "A \<union> Aa" in exI)
   250 apply (auto intro!: lam_type intro: Finite_Un simp add: multiset_fun_iff zero_less_add)
   250 apply (auto intro!: lam_type intro: Finite_Un simp add: multiset_fun_iff zero_less_add)
   251 done
   251 done
   252 
   252 
   257 
   257 
   258 (** Algebraic properties of multisets **)
   258 (** Algebraic properties of multisets **)
   259 
   259 
   260 (* Union *)
   260 (* Union *)
   261 
   261 
   262 lemma munion_0 [simp]: "multiset(M) ==> M +# 0 = M & 0 +# M = M"
   262 lemma munion_0 [simp]: "multiset(M) \<Longrightarrow> M +# 0 = M & 0 +# M = M"
   263 apply (simp add: multiset_def)
   263 apply (simp add: multiset_def)
   264 apply (auto simp add: munion_def mset_of_def)
   264 apply (auto simp add: munion_def mset_of_def)
   265 done
   265 done
   266 
   266 
   267 lemma munion_commute: "M +# N = N +# M"
   267 lemma munion_commute: "M +# N = N +# M"
   285 by (simp add: mdiff_def normalize_def mset_of_def)
   285 by (simp add: mdiff_def normalize_def mset_of_def)
   286 
   286 
   287 lemma mdiff_0 [simp]: "0 -# M = 0"
   287 lemma mdiff_0 [simp]: "0 -# M = 0"
   288 by (simp add: mdiff_def normalize_def)
   288 by (simp add: mdiff_def normalize_def)
   289 
   289 
   290 lemma mdiff_0_right [simp]: "multiset(M) ==> M -# 0 = M"
   290 lemma mdiff_0_right [simp]: "multiset(M) \<Longrightarrow> M -# 0 = M"
   291 by (auto simp add: multiset_def mdiff_def normalize_def multiset_fun_iff mset_of_def funrestrict_def)
   291 by (auto simp add: multiset_def mdiff_def normalize_def multiset_fun_iff mset_of_def funrestrict_def)
   292 
   292 
   293 lemma mdiff_union_inverse2 [simp]: "multiset(M) ==> M +# {#a#} -# {#a#} = M"
   293 lemma mdiff_union_inverse2 [simp]: "multiset(M) \<Longrightarrow> M +# {#a#} -# {#a#} = M"
   294 apply (unfold multiset_def munion_def mdiff_def msingle_def normalize_def mset_of_def)
   294 apply (unfold multiset_def munion_def mdiff_def msingle_def normalize_def mset_of_def)
   295 apply (auto cong add: if_cong simp add: ltD multiset_fun_iff funrestrict_def subset_Un_iff2 [THEN iffD1])
   295 apply (auto cong add: if_cong simp add: ltD multiset_fun_iff funrestrict_def subset_Un_iff2 [THEN iffD1])
   296 prefer 2 apply (force intro!: lam_type)
   296 prefer 2 apply (force intro!: lam_type)
   297 apply (subgoal_tac [2] "{x \<in> A \<union> {a} . x \<noteq> a \<and> x \<in> A} = A")
   297 apply (subgoal_tac [2] "{x \<in> A \<union> {a} . x \<noteq> a \<and> x \<in> A} = A")
   298 apply (rule fun_extension, auto)
   298 apply (rule fun_extension, auto)
   301 apply (force intro!: lam_type)
   301 apply (force intro!: lam_type)
   302 done
   302 done
   303 
   303 
   304 (** Count of elements **)
   304 (** Count of elements **)
   305 
   305 
   306 lemma mcount_type [simp,TC]: "multiset(M) ==> mcount(M, a) \<in> nat"
   306 lemma mcount_type [simp,TC]: "multiset(M) \<Longrightarrow> mcount(M, a) \<in> nat"
   307 by (auto simp add: multiset_def mcount_def mset_of_def multiset_fun_iff)
   307 by (auto simp add: multiset_def mcount_def mset_of_def multiset_fun_iff)
   308 
   308 
   309 lemma mcount_0 [simp]: "mcount(0, a) = 0"
   309 lemma mcount_0 [simp]: "mcount(0, a) = 0"
   310 by (simp add: mcount_def)
   310 by (simp add: mcount_def)
   311 
   311 
   312 lemma mcount_single [simp]: "mcount({#b#}, a) = (if a=b then 1 else 0)"
   312 lemma mcount_single [simp]: "mcount({#b#}, a) = (if a=b then 1 else 0)"
   313 by (simp add: mcount_def mset_of_def msingle_def)
   313 by (simp add: mcount_def mset_of_def msingle_def)
   314 
   314 
   315 lemma mcount_union [simp]: "[| multiset(M); multiset(N) |]
   315 lemma mcount_union [simp]: "\<lbrakk>multiset(M); multiset(N)\<rbrakk>
   316                      ==>  mcount(M +# N, a) = mcount(M, a) #+ mcount (N, a)"
   316                      \<Longrightarrow>  mcount(M +# N, a) = mcount(M, a) #+ mcount (N, a)"
   317 apply (auto simp add: multiset_def multiset_fun_iff mcount_def munion_def mset_of_def)
   317 apply (auto simp add: multiset_def multiset_fun_iff mcount_def munion_def mset_of_def)
   318 done
   318 done
   319 
   319 
   320 lemma mcount_diff [simp]:
   320 lemma mcount_diff [simp]:
   321      "multiset(M) ==> mcount(M -# N, a) = mcount(M, a) #- mcount(N, a)"
   321      "multiset(M) \<Longrightarrow> mcount(M -# N, a) = mcount(M, a) #- mcount(N, a)"
   322 apply (simp add: multiset_def)
   322 apply (simp add: multiset_def)
   323 apply (auto dest!: not_lt_imp_le
   323 apply (auto dest!: not_lt_imp_le
   324      simp add: mdiff_def multiset_fun_iff mcount_def normalize_def mset_of_def)
   324      simp add: mdiff_def multiset_fun_iff mcount_def normalize_def mset_of_def)
   325 apply (force intro!: lam_type)
   325 apply (force intro!: lam_type)
   326 apply (force intro!: lam_type)
   326 apply (force intro!: lam_type)
   327 done
   327 done
   328 
   328 
   329 lemma mcount_elem: "[| multiset(M); a \<in> mset_of(M) |] ==> 0 < mcount(M, a)"
   329 lemma mcount_elem: "\<lbrakk>multiset(M); a \<in> mset_of(M)\<rbrakk> \<Longrightarrow> 0 < mcount(M, a)"
   330 apply (simp add: multiset_def, clarify)
   330 apply (simp add: multiset_def, clarify)
   331 apply (simp add: mcount_def mset_of_def)
   331 apply (simp add: mcount_def mset_of_def)
   332 apply (simp add: multiset_fun_iff)
   332 apply (simp add: multiset_fun_iff)
   333 done
   333 done
   334 
   334 
   341 by (simp add: msize_def)
   341 by (simp add: msize_def)
   342 
   342 
   343 lemma msize_type [simp,TC]: "msize(M) \<in> int"
   343 lemma msize_type [simp,TC]: "msize(M) \<in> int"
   344 by (simp add: msize_def)
   344 by (simp add: msize_def)
   345 
   345 
   346 lemma msize_zpositive: "multiset(M)==> #0 $\<le> msize(M)"
   346 lemma msize_zpositive: "multiset(M)\<Longrightarrow> #0 $\<le> msize(M)"
   347 by (auto simp add: msize_def intro: g_zpos_imp_setsum_zpos)
   347 by (auto simp add: msize_def intro: g_zpos_imp_setsum_zpos)
   348 
   348 
   349 lemma msize_int_of_nat: "multiset(M) ==> \<exists>n \<in> nat. msize(M)= $# n"
   349 lemma msize_int_of_nat: "multiset(M) \<Longrightarrow> \<exists>n \<in> nat. msize(M)= $# n"
   350 apply (rule not_zneg_int_of)
   350 apply (rule not_zneg_int_of)
   351 apply (simp_all (no_asm_simp) add: msize_type [THEN znegative_iff_zless_0] not_zless_iff_zle msize_zpositive)
   351 apply (simp_all (no_asm_simp) add: msize_type [THEN znegative_iff_zless_0] not_zless_iff_zle msize_zpositive)
   352 done
   352 done
   353 
   353 
   354 lemma not_empty_multiset_imp_exist:
   354 lemma not_empty_multiset_imp_exist:
   355      "[| M\<noteq>0; multiset(M) |] ==> \<exists>a \<in> mset_of(M). 0 < mcount(M, a)"
   355      "\<lbrakk>M\<noteq>0; multiset(M)\<rbrakk> \<Longrightarrow> \<exists>a \<in> mset_of(M). 0 < mcount(M, a)"
   356 apply (simp add: multiset_def)
   356 apply (simp add: multiset_def)
   357 apply (erule not_emptyE)
   357 apply (erule not_emptyE)
   358 apply (auto simp add: mset_of_def mcount_def multiset_fun_iff)
   358 apply (auto simp add: mset_of_def mcount_def multiset_fun_iff)
   359 apply (blast dest!: fun_is_rel)
   359 apply (blast dest!: fun_is_rel)
   360 done
   360 done
   361 
   361 
   362 lemma msize_eq_0_iff: "multiset(M) ==> msize(M)=#0 \<longleftrightarrow> M=0"
   362 lemma msize_eq_0_iff: "multiset(M) \<Longrightarrow> msize(M)=#0 \<longleftrightarrow> M=0"
   363 apply (simp add: msize_def, auto)
   363 apply (simp add: msize_def, auto)
   364 apply (rule_tac P = "setsum (u,v) \<noteq> #0" for u v in swap)
   364 apply (rule_tac P = "setsum (u,v) \<noteq> #0" for u v in swap)
   365 apply blast
   365 apply blast
   366 apply (drule not_empty_multiset_imp_exist, assumption, clarify)
   366 apply (drule not_empty_multiset_imp_exist, assumption, clarify)
   367 apply (subgoal_tac "Finite (mset_of (M) - {a}) ")
   367 apply (subgoal_tac "Finite (mset_of (M) - {a}) ")
   374 apply (rule not_zneg_int_of [THEN bexE])
   374 apply (rule not_zneg_int_of [THEN bexE])
   375 apply (auto simp del: int_of_0 simp add: int_of_add [symmetric] int_of_0 [symmetric])
   375 apply (auto simp del: int_of_0 simp add: int_of_add [symmetric] int_of_0 [symmetric])
   376 done
   376 done
   377 
   377 
   378 lemma setsum_mcount_Int:
   378 lemma setsum_mcount_Int:
   379      "Finite(A) ==> setsum(%a. $# mcount(N, a), A \<inter> mset_of(N))
   379      "Finite(A) \<Longrightarrow> setsum(%a. $# mcount(N, a), A \<inter> mset_of(N))
   380                   = setsum(%a. $# mcount(N, a), A)"
   380                   = setsum(%a. $# mcount(N, a), A)"
   381 apply (induct rule: Finite_induct)
   381 apply (induct rule: Finite_induct)
   382  apply auto
   382  apply auto
   383 apply (subgoal_tac "Finite (B \<inter> mset_of (N))")
   383 apply (subgoal_tac "Finite (B \<inter> mset_of (N))")
   384 prefer 2 apply (blast intro: subset_Finite)
   384 prefer 2 apply (blast intro: subset_Finite)
   385 apply (auto simp add: mcount_def Int_cons_left)
   385 apply (auto simp add: mcount_def Int_cons_left)
   386 done
   386 done
   387 
   387 
   388 lemma msize_union [simp]:
   388 lemma msize_union [simp]:
   389      "[| multiset(M); multiset(N) |] ==> msize(M +# N) = msize(M) $+ msize(N)"
   389      "\<lbrakk>multiset(M); multiset(N)\<rbrakk> \<Longrightarrow> msize(M +# N) = msize(M) $+ msize(N)"
   390 apply (simp add: msize_def setsum_Un setsum_addf int_of_add setsum_mcount_Int)
   390 apply (simp add: msize_def setsum_Un setsum_addf int_of_add setsum_mcount_Int)
   391 apply (subst Int_commute)
   391 apply (subst Int_commute)
   392 apply (simp add: setsum_mcount_Int)
   392 apply (simp add: setsum_mcount_Int)
   393 done
   393 done
   394 
   394 
   395 lemma msize_eq_succ_imp_elem: "[|msize(M)= $# succ(n); n \<in> nat|] ==> \<exists>a. a \<in> mset_of(M)"
   395 lemma msize_eq_succ_imp_elem: "\<lbrakk>msize(M)= $# succ(n); n \<in> nat\<rbrakk> \<Longrightarrow> \<exists>a. a \<in> mset_of(M)"
   396 apply (unfold msize_def)
   396 apply (unfold msize_def)
   397 apply (blast dest: setsum_succD)
   397 apply (blast dest: setsum_succD)
   398 done
   398 done
   399 
   399 
   400 (** Equality of multisets **)
   400 (** Equality of multisets **)
   401 
   401 
   402 lemma equality_lemma:
   402 lemma equality_lemma:
   403      "[| multiset(M); multiset(N); \<forall>a. mcount(M, a)=mcount(N, a) |]
   403      "\<lbrakk>multiset(M); multiset(N); \<forall>a. mcount(M, a)=mcount(N, a)\<rbrakk>
   404       ==> mset_of(M)=mset_of(N)"
   404       \<Longrightarrow> mset_of(M)=mset_of(N)"
   405 apply (simp add: multiset_def)
   405 apply (simp add: multiset_def)
   406 apply (rule sym, rule equalityI)
   406 apply (rule sym, rule equalityI)
   407 apply (auto simp add: multiset_fun_iff mcount_def mset_of_def)
   407 apply (auto simp add: multiset_fun_iff mcount_def mset_of_def)
   408 apply (drule_tac [!] x=x in spec)
   408 apply (drule_tac [!] x=x in spec)
   409 apply (case_tac [2] "x \<in> Aa", case_tac "x \<in> A", auto)
   409 apply (case_tac [2] "x \<in> Aa", case_tac "x \<in> A", auto)
   410 done
   410 done
   411 
   411 
   412 lemma multiset_equality:
   412 lemma multiset_equality:
   413   "[| multiset(M); multiset(N) |]==> M=N\<longleftrightarrow>(\<forall>a. mcount(M, a)=mcount(N, a))"
   413   "\<lbrakk>multiset(M); multiset(N)\<rbrakk>\<Longrightarrow> M=N\<longleftrightarrow>(\<forall>a. mcount(M, a)=mcount(N, a))"
   414 apply auto
   414 apply auto
   415 apply (subgoal_tac "mset_of (M) = mset_of (N) ")
   415 apply (subgoal_tac "mset_of (M) = mset_of (N) ")
   416 prefer 2 apply (blast intro: equality_lemma)
   416 prefer 2 apply (blast intro: equality_lemma)
   417 apply (simp add: multiset_def mset_of_def)
   417 apply (simp add: multiset_def mset_of_def)
   418 apply (auto simp add: multiset_fun_iff)
   418 apply (auto simp add: multiset_fun_iff)
   422 apply (auto simp add: mcount_def mset_of_def)
   422 apply (auto simp add: mcount_def mset_of_def)
   423 done
   423 done
   424 
   424 
   425 (** More algebraic properties of multisets **)
   425 (** More algebraic properties of multisets **)
   426 
   426 
   427 lemma munion_eq_0_iff [simp]: "[|multiset(M); multiset(N)|]==>(M +# N =0) \<longleftrightarrow> (M=0 & N=0)"
   427 lemma munion_eq_0_iff [simp]: "\<lbrakk>multiset(M); multiset(N)\<rbrakk>\<Longrightarrow>(M +# N =0) \<longleftrightarrow> (M=0 & N=0)"
   428 by (auto simp add: multiset_equality)
   428 by (auto simp add: multiset_equality)
   429 
   429 
   430 lemma empty_eq_munion_iff [simp]: "[|multiset(M); multiset(N)|]==>(0=M +# N) \<longleftrightarrow> (M=0 & N=0)"
   430 lemma empty_eq_munion_iff [simp]: "\<lbrakk>multiset(M); multiset(N)\<rbrakk>\<Longrightarrow>(0=M +# N) \<longleftrightarrow> (M=0 & N=0)"
   431 apply (rule iffI, drule sym)
   431 apply (rule iffI, drule sym)
   432 apply (simp_all add: multiset_equality)
   432 apply (simp_all add: multiset_equality)
   433 done
   433 done
   434 
   434 
   435 lemma munion_right_cancel [simp]:
   435 lemma munion_right_cancel [simp]:
   436      "[| multiset(M); multiset(N); multiset(K) |]==>(M +# K = N +# K)\<longleftrightarrow>(M=N)"
   436      "\<lbrakk>multiset(M); multiset(N); multiset(K)\<rbrakk>\<Longrightarrow>(M +# K = N +# K)\<longleftrightarrow>(M=N)"
   437 by (auto simp add: multiset_equality)
   437 by (auto simp add: multiset_equality)
   438 
   438 
   439 lemma munion_left_cancel [simp]:
   439 lemma munion_left_cancel [simp]:
   440   "[|multiset(K); multiset(M); multiset(N)|] ==>(K +# M = K +# N) \<longleftrightarrow> (M = N)"
   440   "\<lbrakk>multiset(K); multiset(M); multiset(N)\<rbrakk> \<Longrightarrow>(K +# M = K +# N) \<longleftrightarrow> (M = N)"
   441 by (auto simp add: multiset_equality)
   441 by (auto simp add: multiset_equality)
   442 
   442 
   443 lemma nat_add_eq_1_cases: "[| m \<in> nat; n \<in> nat |] ==> (m #+ n = 1) \<longleftrightarrow> (m=1 & n=0) | (m=0 & n=1)"
   443 lemma nat_add_eq_1_cases: "\<lbrakk>m \<in> nat; n \<in> nat\<rbrakk> \<Longrightarrow> (m #+ n = 1) \<longleftrightarrow> (m=1 & n=0) | (m=0 & n=1)"
   444 by (induct_tac n) auto
   444 by (induct_tac n) auto
   445 
   445 
   446 lemma munion_is_single:
   446 lemma munion_is_single:
   447      "[|multiset(M); multiset(N)|]
   447      "\<lbrakk>multiset(M); multiset(N)\<rbrakk>
   448       ==> (M +# N = {#a#}) \<longleftrightarrow>  (M={#a#} & N=0) | (M = 0 & N = {#a#})"
   448       \<Longrightarrow> (M +# N = {#a#}) \<longleftrightarrow>  (M={#a#} & N=0) | (M = 0 & N = {#a#})"
   449 apply (simp (no_asm_simp) add: multiset_equality)
   449 apply (simp (no_asm_simp) add: multiset_equality)
   450 apply safe
   450 apply safe
   451 apply simp_all
   451 apply simp_all
   452 apply (case_tac "aa=a")
   452 apply (case_tac "aa=a")
   453 apply (drule_tac [2] x = aa in spec)
   453 apply (drule_tac [2] x = aa in spec)
   462 apply (drule_tac [2] x = aaa in spec)
   462 apply (drule_tac [2] x = aaa in spec)
   463 apply (drule_tac x = aa in spec)
   463 apply (drule_tac x = aa in spec)
   464 apply (simp_all add: nat_add_eq_1_cases)
   464 apply (simp_all add: nat_add_eq_1_cases)
   465 done
   465 done
   466 
   466 
   467 lemma msingle_is_union: "[| multiset(M); multiset(N) |]
   467 lemma msingle_is_union: "\<lbrakk>multiset(M); multiset(N)\<rbrakk>
   468   ==> ({#a#} = M +# N) \<longleftrightarrow> ({#a#} = M  & N=0 | M = 0 & {#a#} = N)"
   468   \<Longrightarrow> ({#a#} = M +# N) \<longleftrightarrow> ({#a#} = M  & N=0 | M = 0 & {#a#} = N)"
   469 apply (subgoal_tac " ({#a#} = M +# N) \<longleftrightarrow> (M +# N = {#a#}) ")
   469 apply (subgoal_tac " ({#a#} = M +# N) \<longleftrightarrow> (M +# N = {#a#}) ")
   470 apply (simp (no_asm_simp) add: munion_is_single)
   470 apply (simp (no_asm_simp) add: munion_is_single)
   471 apply blast
   471 apply blast
   472 apply (blast dest: sym)
   472 apply (blast dest: sym)
   473 done
   473 done
   474 
   474 
   475 (** Towards induction over multisets **)
   475 (** Towards induction over multisets **)
   476 
   476 
   477 lemma setsum_decr:
   477 lemma setsum_decr:
   478 "Finite(A)
   478 "Finite(A)
   479   ==>  (\<forall>M. multiset(M) \<longrightarrow>
   479   \<Longrightarrow>  (\<forall>M. multiset(M) \<longrightarrow>
   480   (\<forall>a \<in> mset_of(M). setsum(%z. $# mcount(M(a:=M`a #- 1), z), A) =
   480   (\<forall>a \<in> mset_of(M). setsum(%z. $# mcount(M(a:=M`a #- 1), z), A) =
   481   (if a \<in> A then setsum(%z. $# mcount(M, z), A) $- #1
   481   (if a \<in> A then setsum(%z. $# mcount(M, z), A) $- #1
   482            else setsum(%z. $# mcount(M, z), A))))"
   482            else setsum(%z. $# mcount(M, z), A))))"
   483 apply (unfold multiset_def)
   483 apply (unfold multiset_def)
   484 apply (erule Finite_induct)
   484 apply (erule Finite_induct)
   490 apply (rule int_of_diff, auto)
   490 apply (rule int_of_diff, auto)
   491 done
   491 done
   492 
   492 
   493 lemma setsum_decr2:
   493 lemma setsum_decr2:
   494      "Finite(A)
   494      "Finite(A)
   495       ==> \<forall>M. multiset(M) \<longrightarrow> (\<forall>a \<in> mset_of(M).
   495       \<Longrightarrow> \<forall>M. multiset(M) \<longrightarrow> (\<forall>a \<in> mset_of(M).
   496            setsum(%x. $# mcount(funrestrict(M, mset_of(M)-{a}), x), A) =
   496            setsum(%x. $# mcount(funrestrict(M, mset_of(M)-{a}), x), A) =
   497            (if a \<in> A then setsum(%x. $# mcount(M, x), A) $- $# M`a
   497            (if a \<in> A then setsum(%x. $# mcount(M, x), A) $- $# M`a
   498             else setsum(%x. $# mcount(M, x), A)))"
   498             else setsum(%x. $# mcount(M, x), A)))"
   499 apply (simp add: multiset_def)
   499 apply (simp add: multiset_def)
   500 apply (erule Finite_induct)
   500 apply (erule Finite_induct)
   501 apply (auto simp add: multiset_fun_iff mcount_def mset_of_def)
   501 apply (auto simp add: multiset_fun_iff mcount_def mset_of_def)
   502 done
   502 done
   503 
   503 
   504 lemma setsum_decr3: "[| Finite(A); multiset(M); a \<in> mset_of(M) |]
   504 lemma setsum_decr3: "\<lbrakk>Finite(A); multiset(M); a \<in> mset_of(M)\<rbrakk>
   505       ==> setsum(%x. $# mcount(funrestrict(M, mset_of(M)-{a}), x), A - {a}) =
   505       \<Longrightarrow> setsum(%x. $# mcount(funrestrict(M, mset_of(M)-{a}), x), A - {a}) =
   506           (if a \<in> A then setsum(%x. $# mcount(M, x), A) $- $# M`a
   506           (if a \<in> A then setsum(%x. $# mcount(M, x), A) $- $# M`a
   507            else setsum(%x. $# mcount(M, x), A))"
   507            else setsum(%x. $# mcount(M, x), A))"
   508 apply (subgoal_tac "setsum (%x. $# mcount (funrestrict (M, mset_of (M) -{a}),x),A-{a}) = setsum (%x. $# mcount (funrestrict (M, mset_of (M) -{a}),x),A) ")
   508 apply (subgoal_tac "setsum (%x. $# mcount (funrestrict (M, mset_of (M) -{a}),x),A-{a}) = setsum (%x. $# mcount (funrestrict (M, mset_of (M) -{a}),x),A) ")
   509 apply (rule_tac [2] setsum_Diff [symmetric])
   509 apply (rule_tac [2] setsum_Diff [symmetric])
   510 apply (rule sym, rule ssubst, blast)
   510 apply (rule sym, rule ssubst, blast)
   511 apply (rule sym, drule setsum_decr2, auto)
   511 apply (rule sym, drule setsum_decr2, auto)
   512 apply (simp add: mcount_def mset_of_def)
   512 apply (simp add: mcount_def mset_of_def)
   513 done
   513 done
   514 
   514 
   515 lemma nat_le_1_cases: "n \<in> nat ==> n \<le> 1 \<longleftrightarrow> (n=0 | n=1)"
   515 lemma nat_le_1_cases: "n \<in> nat \<Longrightarrow> n \<le> 1 \<longleftrightarrow> (n=0 | n=1)"
   516 by (auto elim: natE)
   516 by (auto elim: natE)
   517 
   517 
   518 lemma succ_pred_eq_self: "[| 0<n; n \<in> nat |] ==> succ(n #- 1) = n"
   518 lemma succ_pred_eq_self: "\<lbrakk>0<n; n \<in> nat\<rbrakk> \<Longrightarrow> succ(n #- 1) = n"
   519 apply (subgoal_tac "1 \<le> n")
   519 apply (subgoal_tac "1 \<le> n")
   520 apply (drule add_diff_inverse2, auto)
   520 apply (drule add_diff_inverse2, auto)
   521 done
   521 done
   522 
   522 
   523 text\<open>Specialized for use in the proof below.\<close>
   523 text\<open>Specialized for use in the proof below.\<close>
   528 apply (rule_tac x="A-{a}" in exI)
   528 apply (rule_tac x="A-{a}" in exI)
   529 apply (auto intro: Finite_Diff funrestrict_type)
   529 apply (auto intro: Finite_Diff funrestrict_type)
   530 done
   530 done
   531 
   531 
   532 lemma multiset_induct_aux:
   532 lemma multiset_induct_aux:
   533   assumes prem1: "!!M a. [| multiset(M); a\<notin>mset_of(M); P(M) |] ==> P(cons(<a, 1>, M))"
   533   assumes prem1: "\<And>M a. \<lbrakk>multiset(M); a\<notin>mset_of(M); P(M)\<rbrakk> \<Longrightarrow> P(cons(<a, 1>, M))"
   534       and prem2: "!!M b. [| multiset(M); b \<in> mset_of(M); P(M) |] ==> P(M(b:= M`b #+ 1))"
   534       and prem2: "\<And>M b. \<lbrakk>multiset(M); b \<in> mset_of(M); P(M)\<rbrakk> \<Longrightarrow> P(M(b:= M`b #+ 1))"
   535   shows
   535   shows
   536   "[| n \<in> nat; P(0) |]
   536   "\<lbrakk>n \<in> nat; P(0)\<rbrakk>
   537      ==> (\<forall>M. multiset(M)\<longrightarrow>
   537      \<Longrightarrow> (\<forall>M. multiset(M)\<longrightarrow>
   538   (setsum(%x. $# mcount(M, x), {x \<in> mset_of(M). 0 < M`x}) = $# n) \<longrightarrow> P(M))"
   538   (setsum(%x. $# mcount(M, x), {x \<in> mset_of(M). 0 < M`x}) = $# n) \<longrightarrow> P(M))"
   539 apply (erule nat_induct, clarify)
   539 apply (erule nat_induct, clarify)
   540 apply (frule msize_eq_0_iff)
   540 apply (frule msize_eq_0_iff)
   541 apply (auto simp add: mset_of_def multiset_def multiset_fun_iff msize_def)
   541 apply (auto simp add: mset_of_def multiset_def multiset_fun_iff msize_def)
   542 apply (subgoal_tac "setsum (%x. $# mcount (M, x), A) =$# succ (x) ")
   542 apply (subgoal_tac "setsum (%x. $# mcount (M, x), A) =$# succ (x) ")
   598 apply (subgoal_tac "{x \<in> A - {a} . 0 < funrestrict (M, A - {x}) ` x} = A - {a}")
   598 apply (subgoal_tac "{x \<in> A - {a} . 0 < funrestrict (M, A - {x}) ` x} = A - {a}")
   599 apply (auto intro!: setsum_cong simp add: zdiff_eq_iff zadd_commute multiset_def multiset_fun_iff mset_of_def)
   599 apply (auto intro!: setsum_cong simp add: zdiff_eq_iff zadd_commute multiset_def multiset_fun_iff mset_of_def)
   600 done
   600 done
   601 
   601 
   602 lemma multiset_induct2:
   602 lemma multiset_induct2:
   603   "[| multiset(M); P(0);
   603   "\<lbrakk>multiset(M); P(0);
   604     (!!M a. [| multiset(M); a\<notin>mset_of(M); P(M) |] ==> P(cons(<a, 1>, M)));
   604     (\<And>M a. \<lbrakk>multiset(M); a\<notin>mset_of(M); P(M)\<rbrakk> \<Longrightarrow> P(cons(<a, 1>, M)));
   605     (!!M b. [| multiset(M); b \<in> mset_of(M);  P(M) |] ==> P(M(b:= M`b #+ 1))) |]
   605     (\<And>M b. \<lbrakk>multiset(M); b \<in> mset_of(M);  P(M)\<rbrakk> \<Longrightarrow> P(M(b:= M`b #+ 1)))\<rbrakk>
   606      ==> P(M)"
   606      \<Longrightarrow> P(M)"
   607 apply (subgoal_tac "\<exists>n \<in> nat. setsum (\<lambda>x. $# mcount (M, x), {x \<in> mset_of (M) . 0 < M ` x}) = $# n")
   607 apply (subgoal_tac "\<exists>n \<in> nat. setsum (\<lambda>x. $# mcount (M, x), {x \<in> mset_of (M) . 0 < M ` x}) = $# n")
   608 apply (rule_tac [2] not_zneg_int_of)
   608 apply (rule_tac [2] not_zneg_int_of)
   609 apply (simp_all (no_asm_simp) add: znegative_iff_zless_0 not_zless_iff_zle)
   609 apply (simp_all (no_asm_simp) add: znegative_iff_zless_0 not_zless_iff_zle)
   610 apply (rule_tac [2] g_zpos_imp_setsum_zpos)
   610 apply (rule_tac [2] g_zpos_imp_setsum_zpos)
   611 prefer 2 apply (blast intro:  multiset_set_of_Finite Collect_subset [THEN subset_Finite])
   611 prefer 2 apply (blast intro:  multiset_set_of_Finite Collect_subset [THEN subset_Finite])
   612  prefer 2 apply (simp add: multiset_def multiset_fun_iff, clarify)
   612  prefer 2 apply (simp add: multiset_def multiset_fun_iff, clarify)
   613 apply (rule multiset_induct_aux [rule_format], auto)
   613 apply (rule multiset_induct_aux [rule_format], auto)
   614 done
   614 done
   615 
   615 
   616 lemma munion_single_case1:
   616 lemma munion_single_case1:
   617      "[| multiset(M); a \<notin>mset_of(M) |] ==> M +# {#a#} = cons(<a, 1>, M)"
   617      "\<lbrakk>multiset(M); a \<notin>mset_of(M)\<rbrakk> \<Longrightarrow> M +# {#a#} = cons(<a, 1>, M)"
   618 apply (simp add: multiset_def msingle_def)
   618 apply (simp add: multiset_def msingle_def)
   619 apply (auto simp add: munion_def)
   619 apply (auto simp add: munion_def)
   620 apply (unfold mset_of_def, simp)
   620 apply (unfold mset_of_def, simp)
   621 apply (rule fun_extension, rule lam_type, simp_all)
   621 apply (rule fun_extension, rule lam_type, simp_all)
   622 apply (auto simp add: multiset_fun_iff fun_extend_apply)
   622 apply (auto simp add: multiset_fun_iff fun_extend_apply)
   623 apply (drule_tac c = a and b = 1 in fun_extend3)
   623 apply (drule_tac c = a and b = 1 in fun_extend3)
   624 apply (auto simp add: cons_eq Un_commute [of _ "{a}"])
   624 apply (auto simp add: cons_eq Un_commute [of _ "{a}"])
   625 done
   625 done
   626 
   626 
   627 lemma munion_single_case2:
   627 lemma munion_single_case2:
   628      "[| multiset(M); a \<in> mset_of(M) |] ==> M +# {#a#} = M(a:=M`a #+ 1)"
   628      "\<lbrakk>multiset(M); a \<in> mset_of(M)\<rbrakk> \<Longrightarrow> M +# {#a#} = M(a:=M`a #+ 1)"
   629 apply (simp add: multiset_def)
   629 apply (simp add: multiset_def)
   630 apply (auto simp add: munion_def multiset_fun_iff msingle_def)
   630 apply (auto simp add: munion_def multiset_fun_iff msingle_def)
   631 apply (unfold mset_of_def, simp)
   631 apply (unfold mset_of_def, simp)
   632 apply (subgoal_tac "A \<union> {a} = A")
   632 apply (subgoal_tac "A \<union> {a} = A")
   633 apply (rule fun_extension)
   633 apply (rule fun_extension)
   637 (* Induction principle for multisets *)
   637 (* Induction principle for multisets *)
   638 
   638 
   639 lemma multiset_induct:
   639 lemma multiset_induct:
   640   assumes M: "multiset(M)"
   640   assumes M: "multiset(M)"
   641       and P0: "P(0)"
   641       and P0: "P(0)"
   642       and step: "!!M a. [| multiset(M); P(M) |] ==> P(M +# {#a#})"
   642       and step: "\<And>M a. \<lbrakk>multiset(M); P(M)\<rbrakk> \<Longrightarrow> P(M +# {#a#})"
   643   shows "P(M)"
   643   shows "P(M)"
   644 apply (rule multiset_induct2 [OF M])
   644 apply (rule multiset_induct2 [OF M])
   645 apply (simp_all add: P0)
   645 apply (simp_all add: P0)
   646 apply (frule_tac [2] a = b in munion_single_case2 [symmetric])
   646 apply (frule_tac [2] a = b in munion_single_case2 [symmetric])
   647 apply (frule_tac a = a in munion_single_case1 [symmetric])
   647 apply (frule_tac a = a in munion_single_case1 [symmetric])
   649 done
   649 done
   650 
   650 
   651 (** MCollect **)
   651 (** MCollect **)
   652 
   652 
   653 lemma MCollect_multiset [simp]:
   653 lemma MCollect_multiset [simp]:
   654      "multiset(M) ==> multiset({# x \<in> M. P(x)#})"
   654      "multiset(M) \<Longrightarrow> multiset({# x \<in> M. P(x)#})"
   655 apply (simp add: MCollect_def multiset_def mset_of_def, clarify)
   655 apply (simp add: MCollect_def multiset_def mset_of_def, clarify)
   656 apply (rule_tac x = "{x \<in> A. P (x) }" in exI)
   656 apply (rule_tac x = "{x \<in> A. P (x) }" in exI)
   657 apply (auto dest: CollectD1 [THEN [2] apply_type]
   657 apply (auto dest: CollectD1 [THEN [2] apply_type]
   658             intro: Collect_subset [THEN subset_Finite] funrestrict_type)
   658             intro: Collect_subset [THEN subset_Finite] funrestrict_type)
   659 done
   659 done
   660 
   660 
   661 lemma mset_of_MCollect [simp]:
   661 lemma mset_of_MCollect [simp]:
   662      "multiset(M) ==> mset_of({# x \<in> M. P(x) #}) \<subseteq> mset_of(M)"
   662      "multiset(M) \<Longrightarrow> mset_of({# x \<in> M. P(x) #}) \<subseteq> mset_of(M)"
   663 by (auto simp add: mset_of_def MCollect_def multiset_def funrestrict_def)
   663 by (auto simp add: mset_of_def MCollect_def multiset_def funrestrict_def)
   664 
   664 
   665 lemma MCollect_mem_iff [iff]:
   665 lemma MCollect_mem_iff [iff]:
   666      "x \<in> mset_of({#x \<in> M. P(x)#}) \<longleftrightarrow>  x \<in> mset_of(M) & P(x)"
   666      "x \<in> mset_of({#x \<in> M. P(x)#}) \<longleftrightarrow>  x \<in> mset_of(M) & P(x)"
   667 by (simp add: MCollect_def mset_of_def)
   667 by (simp add: MCollect_def mset_of_def)
   668 
   668 
   669 lemma mcount_MCollect [simp]:
   669 lemma mcount_MCollect [simp]:
   670      "mcount({# x \<in> M. P(x) #}, a) = (if P(a) then mcount(M,a) else 0)"
   670      "mcount({# x \<in> M. P(x) #}, a) = (if P(a) then mcount(M,a) else 0)"
   671 by (simp add: mcount_def MCollect_def mset_of_def)
   671 by (simp add: mcount_def MCollect_def mset_of_def)
   672 
   672 
   673 lemma multiset_partition: "multiset(M) ==> M = {# x \<in> M. P(x) #} +# {# x \<in> M. ~ P(x) #}"
   673 lemma multiset_partition: "multiset(M) \<Longrightarrow> M = {# x \<in> M. P(x) #} +# {# x \<in> M. \<not> P(x) #}"
   674 by (simp add: multiset_equality)
   674 by (simp add: multiset_equality)
   675 
   675 
   676 lemma natify_elem_is_self [simp]:
   676 lemma natify_elem_is_self [simp]:
   677      "[| multiset(M); a \<in> mset_of(M) |] ==> natify(M`a) = M`a"
   677      "\<lbrakk>multiset(M); a \<in> mset_of(M)\<rbrakk> \<Longrightarrow> natify(M`a) = M`a"
   678 by (auto simp add: multiset_def mset_of_def multiset_fun_iff)
   678 by (auto simp add: multiset_def mset_of_def multiset_fun_iff)
   679 
   679 
   680 (* and more algebraic laws on multisets *)
   680 (* and more algebraic laws on multisets *)
   681 
   681 
   682 lemma munion_eq_conv_diff: "[| multiset(M); multiset(N) |]
   682 lemma munion_eq_conv_diff: "\<lbrakk>multiset(M); multiset(N)\<rbrakk>
   683   ==>  (M +# {#a#} = N +# {#b#}) \<longleftrightarrow>  (M = N & a = b |
   683   \<Longrightarrow>  (M +# {#a#} = N +# {#b#}) \<longleftrightarrow>  (M = N & a = b |
   684        M = N -# {#a#} +# {#b#} & N = M -# {#b#} +# {#a#})"
   684        M = N -# {#a#} +# {#b#} & N = M -# {#b#} +# {#a#})"
   685 apply (simp del: mcount_single add: multiset_equality)
   685 apply (simp del: mcount_single add: multiset_equality)
   686 apply (rule iffI, erule_tac [2] disjE, erule_tac [3] conjE)
   686 apply (rule iffI, erule_tac [2] disjE, erule_tac [3] conjE)
   687 apply (case_tac "a=b", auto)
   687 apply (case_tac "a=b", auto)
   688 apply (drule_tac x = a in spec)
   688 apply (drule_tac x = a in spec)
   692 apply (subgoal_tac [!] "mcount (N,a) :nat")
   692 apply (subgoal_tac [!] "mcount (N,a) :nat")
   693 apply (erule_tac [3] natE, erule natE, auto)
   693 apply (erule_tac [3] natE, erule natE, auto)
   694 done
   694 done
   695 
   695 
   696 lemma melem_diff_single:
   696 lemma melem_diff_single:
   697 "multiset(M) ==>
   697 "multiset(M) \<Longrightarrow>
   698   k \<in> mset_of(M -# {#a#}) \<longleftrightarrow> (k=a & 1 < mcount(M,a)) | (k\<noteq> a & k \<in> mset_of(M))"
   698   k \<in> mset_of(M -# {#a#}) \<longleftrightarrow> (k=a & 1 < mcount(M,a)) | (k\<noteq> a & k \<in> mset_of(M))"
   699 apply (simp add: multiset_def)
   699 apply (simp add: multiset_def)
   700 apply (simp add: normalize_def mset_of_def msingle_def mdiff_def mcount_def)
   700 apply (simp add: normalize_def mset_of_def msingle_def mdiff_def mcount_def)
   701 apply (auto dest: domain_type intro: zero_less_diff [THEN iffD1]
   701 apply (auto dest: domain_type intro: zero_less_diff [THEN iffD1]
   702             simp add: multiset_fun_iff apply_iff)
   702             simp add: multiset_fun_iff apply_iff)
   704 apply (force intro!: lam_type)
   704 apply (force intro!: lam_type)
   705 apply (force intro!: lam_type)
   705 apply (force intro!: lam_type)
   706 done
   706 done
   707 
   707 
   708 lemma munion_eq_conv_exist:
   708 lemma munion_eq_conv_exist:
   709 "[| M \<in> Mult(A); N \<in> Mult(A) |]
   709 "\<lbrakk>M \<in> Mult(A); N \<in> Mult(A)\<rbrakk>
   710   ==> (M +# {#a#} = N +# {#b#}) \<longleftrightarrow>
   710   \<Longrightarrow> (M +# {#a#} = N +# {#b#}) \<longleftrightarrow>
   711       (M=N & a=b | (\<exists>K \<in> Mult(A). M= K +# {#b#} & N=K +# {#a#}))"
   711       (M=N & a=b | (\<exists>K \<in> Mult(A). M= K +# {#b#} & N=K +# {#a#}))"
   712 by (auto simp add: Mult_iff_multiset melem_diff_single munion_eq_conv_diff)
   712 by (auto simp add: Mult_iff_multiset melem_diff_single munion_eq_conv_diff)
   713 
   713 
   714 
   714 
   715 subsection\<open>Multiset Orderings\<close>
   715 subsection\<open>Multiset Orderings\<close>
   733 by (auto simp add: multirel1_def Mult_iff_multiset Bex_def)
   733 by (auto simp add: multirel1_def Mult_iff_multiset Bex_def)
   734 
   734 
   735 
   735 
   736 text\<open>Monotonicity of \<^term>\<open>multirel1\<close>\<close>
   736 text\<open>Monotonicity of \<^term>\<open>multirel1\<close>\<close>
   737 
   737 
   738 lemma multirel1_mono1: "A\<subseteq>B ==> multirel1(A, r)\<subseteq>multirel1(B, r)"
   738 lemma multirel1_mono1: "A\<subseteq>B \<Longrightarrow> multirel1(A, r)\<subseteq>multirel1(B, r)"
   739 apply (auto simp add: multirel1_def)
   739 apply (auto simp add: multirel1_def)
   740 apply (auto simp add: Un_subset_iff Mult_iff_multiset)
   740 apply (auto simp add: Un_subset_iff Mult_iff_multiset)
   741 apply (rule_tac x = a in bexI)
   741 apply (rule_tac x = a in bexI)
   742 apply (rule_tac x = M0 in bexI, simp)
   742 apply (rule_tac x = M0 in bexI, simp)
   743 apply (rule_tac x = K in bexI)
   743 apply (rule_tac x = K in bexI)
   744 apply (auto simp add: Mult_iff_multiset)
   744 apply (auto simp add: Mult_iff_multiset)
   745 done
   745 done
   746 
   746 
   747 lemma multirel1_mono2: "r\<subseteq>s ==> multirel1(A,r)\<subseteq>multirel1(A, s)"
   747 lemma multirel1_mono2: "r\<subseteq>s \<Longrightarrow> multirel1(A,r)\<subseteq>multirel1(A, s)"
   748 apply (simp add: multirel1_def, auto)
   748 apply (simp add: multirel1_def, auto)
   749 apply (rule_tac x = a in bexI)
   749 apply (rule_tac x = a in bexI)
   750 apply (rule_tac x = M0 in bexI)
   750 apply (rule_tac x = M0 in bexI)
   751 apply (simp_all add: Mult_iff_multiset)
   751 apply (simp_all add: Mult_iff_multiset)
   752 apply (rule_tac x = K in bexI)
   752 apply (rule_tac x = K in bexI)
   753 apply (simp_all add: Mult_iff_multiset, auto)
   753 apply (simp_all add: Mult_iff_multiset, auto)
   754 done
   754 done
   755 
   755 
   756 lemma multirel1_mono:
   756 lemma multirel1_mono:
   757      "[| A\<subseteq>B; r\<subseteq>s |] ==> multirel1(A, r) \<subseteq> multirel1(B, s)"
   757      "\<lbrakk>A\<subseteq>B; r\<subseteq>s\<rbrakk> \<Longrightarrow> multirel1(A, r) \<subseteq> multirel1(B, s)"
   758 apply (rule subset_trans)
   758 apply (rule subset_trans)
   759 apply (rule multirel1_mono1)
   759 apply (rule multirel1_mono1)
   760 apply (rule_tac [2] multirel1_mono2, auto)
   760 apply (rule_tac [2] multirel1_mono2, auto)
   761 done
   761 done
   762 
   762 
   763 subsection\<open>Toward the proof of well-foundedness of multirel1\<close>
   763 subsection\<open>Toward the proof of well-foundedness of multirel1\<close>
   764 
   764 
   765 lemma not_less_0 [iff]: "<M,0> \<notin> multirel1(A, r)"
   765 lemma not_less_0 [iff]: "<M,0> \<notin> multirel1(A, r)"
   766 by (auto simp add: multirel1_def Mult_iff_multiset)
   766 by (auto simp add: multirel1_def Mult_iff_multiset)
   767 
   767 
   768 lemma less_munion: "[| <N, M0 +# {#a#}> \<in> multirel1(A, r); M0 \<in> Mult(A) |] ==>
   768 lemma less_munion: "\<lbrakk><N, M0 +# {#a#}> \<in> multirel1(A, r); M0 \<in> Mult(A)\<rbrakk> \<Longrightarrow>
   769   (\<exists>M. <M, M0> \<in> multirel1(A, r) & N = M +# {#a#}) |
   769   (\<exists>M. <M, M0> \<in> multirel1(A, r) & N = M +# {#a#}) |
   770   (\<exists>K. K \<in> Mult(A) & (\<forall>b \<in> mset_of(K). <b, a> \<in> r) & N = M0 +# K)"
   770   (\<exists>K. K \<in> Mult(A) & (\<forall>b \<in> mset_of(K). <b, a> \<in> r) & N = M0 +# K)"
   771 apply (frule multirel1_type [THEN subsetD])
   771 apply (frule multirel1_type [THEN subsetD])
   772 apply (simp add: multirel1_iff)
   772 apply (simp add: multirel1_iff)
   773 apply (auto simp add: munion_eq_conv_exist)
   773 apply (auto simp add: munion_eq_conv_exist)
   774 apply (rule_tac x="Ka +# K" in exI, auto, simp add: Mult_iff_multiset)
   774 apply (rule_tac x="Ka +# K" in exI, auto, simp add: Mult_iff_multiset)
   775 apply (simp (no_asm_simp) add: munion_left_cancel munion_assoc)
   775 apply (simp (no_asm_simp) add: munion_left_cancel munion_assoc)
   776 apply (auto simp add: munion_commute)
   776 apply (auto simp add: munion_commute)
   777 done
   777 done
   778 
   778 
   779 lemma multirel1_base: "[| M \<in> Mult(A); a \<in> A |] ==> <M, M +# {#a#}> \<in> multirel1(A, r)"
   779 lemma multirel1_base: "\<lbrakk>M \<in> Mult(A); a \<in> A\<rbrakk> \<Longrightarrow> <M, M +# {#a#}> \<in> multirel1(A, r)"
   780 apply (auto simp add: multirel1_iff)
   780 apply (auto simp add: multirel1_iff)
   781 apply (simp add: Mult_iff_multiset)
   781 apply (simp add: Mult_iff_multiset)
   782 apply (rule_tac x = a in exI, clarify)
   782 apply (rule_tac x = a in exI, clarify)
   783 apply (rule_tac x = M in exI, simp)
   783 apply (rule_tac x = M in exI, simp)
   784 apply (rule_tac x = 0 in exI, auto)
   784 apply (rule_tac x = 0 in exI, auto)
   785 done
   785 done
   786 
   786 
   787 lemma acc_0: "acc(0)=0"
   787 lemma acc_0: "acc(0)=0"
   788 by (auto intro!: equalityI dest: acc.dom_subset [THEN subsetD])
   788 by (auto intro!: equalityI dest: acc.dom_subset [THEN subsetD])
   789 
   789 
   790 lemma lemma1: "[| \<forall>b \<in> A. <b,a> \<in> r \<longrightarrow>
   790 lemma lemma1: "\<lbrakk>\<forall>b \<in> A. <b,a> \<in> r \<longrightarrow>
   791     (\<forall>M \<in> acc(multirel1(A, r)). M +# {#b#}:acc(multirel1(A, r)));
   791     (\<forall>M \<in> acc(multirel1(A, r)). M +# {#b#}:acc(multirel1(A, r)));
   792     M0 \<in> acc(multirel1(A, r)); a \<in> A;
   792     M0 \<in> acc(multirel1(A, r)); a \<in> A;
   793     \<forall>M. <M,M0> \<in> multirel1(A, r) \<longrightarrow> M +# {#a#} \<in> acc(multirel1(A, r)) |]
   793     \<forall>M. <M,M0> \<in> multirel1(A, r) \<longrightarrow> M +# {#a#} \<in> acc(multirel1(A, r))\<rbrakk>
   794   ==> M0 +# {#a#} \<in> acc(multirel1(A, r))"
   794   \<Longrightarrow> M0 +# {#a#} \<in> acc(multirel1(A, r))"
   795 apply (subgoal_tac "M0 \<in> Mult(A) ")
   795 apply (subgoal_tac "M0 \<in> Mult(A) ")
   796  prefer 2
   796  prefer 2
   797  apply (erule acc.cases)
   797  apply (erule acc.cases)
   798  apply (erule fieldE)
   798  apply (erule fieldE)
   799  apply (auto dest: multirel1_type [THEN subsetD])
   799  apply (auto dest: multirel1_type [THEN subsetD])
   817 apply (simp add: munion_assoc [symmetric])
   817 apply (simp add: munion_assoc [symmetric])
   818 (* subgoal 3 \<in> additional conditions *)
   818 (* subgoal 3 \<in> additional conditions *)
   819 apply (auto intro!: multirel1_base [THEN fieldI2] simp add: Mult_iff_multiset)
   819 apply (auto intro!: multirel1_base [THEN fieldI2] simp add: Mult_iff_multiset)
   820 done
   820 done
   821 
   821 
   822 lemma lemma2: "[| \<forall>b \<in> A. <b,a> \<in> r
   822 lemma lemma2: "\<lbrakk>\<forall>b \<in> A. <b,a> \<in> r
   823    \<longrightarrow> (\<forall>M \<in> acc(multirel1(A, r)). M +# {#b#} :acc(multirel1(A, r)));
   823    \<longrightarrow> (\<forall>M \<in> acc(multirel1(A, r)). M +# {#b#} :acc(multirel1(A, r)));
   824         M \<in> acc(multirel1(A, r)); a \<in> A|] ==> M +# {#a#} \<in> acc(multirel1(A, r))"
   824         M \<in> acc(multirel1(A, r)); a \<in> A\<rbrakk> \<Longrightarrow> M +# {#a#} \<in> acc(multirel1(A, r))"
   825 apply (erule acc_induct)
   825 apply (erule acc_induct)
   826 apply (blast intro: lemma1)
   826 apply (blast intro: lemma1)
   827 done
   827 done
   828 
   828 
   829 lemma lemma3: "[| wf[A](r); a \<in> A |]
   829 lemma lemma3: "\<lbrakk>wf[A](r); a \<in> A\<rbrakk>
   830       ==> \<forall>M \<in> acc(multirel1(A, r)). M +# {#a#} \<in> acc(multirel1(A, r))"
   830       \<Longrightarrow> \<forall>M \<in> acc(multirel1(A, r)). M +# {#a#} \<in> acc(multirel1(A, r))"
   831 apply (erule_tac a = a in wf_on_induct, blast)
   831 apply (erule_tac a = a in wf_on_induct, blast)
   832 apply (blast intro: lemma2)
   832 apply (blast intro: lemma2)
   833 done
   833 done
   834 
   834 
   835 lemma lemma4: "multiset(M) ==> mset_of(M)\<subseteq>A \<longrightarrow>
   835 lemma lemma4: "multiset(M) \<Longrightarrow> mset_of(M)\<subseteq>A \<longrightarrow>
   836    wf[A](r) \<longrightarrow> M \<in> field(multirel1(A, r)) \<longrightarrow> M \<in> acc(multirel1(A, r))"
   836    wf[A](r) \<longrightarrow> M \<in> field(multirel1(A, r)) \<longrightarrow> M \<in> acc(multirel1(A, r))"
   837 apply (erule multiset_induct)
   837 apply (erule multiset_induct)
   838 (* proving the base case *)
   838 (* proving the base case *)
   839 apply clarify
   839 apply clarify
   840 apply (rule accI, force)
   840 apply (rule accI, force)
   850 apply blast
   850 apply blast
   851 apply (rule multirel1_base [THEN fieldI1])
   851 apply (rule multirel1_base [THEN fieldI1])
   852 apply (auto simp add: Mult_iff_multiset)
   852 apply (auto simp add: Mult_iff_multiset)
   853 done
   853 done
   854 
   854 
   855 lemma all_accessible: "[| wf[A](r); M \<in> Mult(A); A \<noteq> 0|] ==> M \<in> acc(multirel1(A, r))"
   855 lemma all_accessible: "\<lbrakk>wf[A](r); M \<in> Mult(A); A \<noteq> 0\<rbrakk> \<Longrightarrow> M \<in> acc(multirel1(A, r))"
   856 apply (erule not_emptyE)
   856 apply (erule not_emptyE)
   857 apply  (rule lemma4 [THEN mp, THEN mp, THEN mp])
   857 apply  (rule lemma4 [THEN mp, THEN mp, THEN mp])
   858 apply (rule_tac [4] multirel1_base [THEN fieldI1])
   858 apply (rule_tac [4] multirel1_base [THEN fieldI1])
   859 apply  (auto simp add: Mult_iff_multiset)
   859 apply  (auto simp add: Mult_iff_multiset)
   860 done
   860 done
   861 
   861 
   862 lemma wf_on_multirel1: "wf[A](r) ==> wf[A-||>nat-{0}](multirel1(A, r))"
   862 lemma wf_on_multirel1: "wf[A](r) \<Longrightarrow> wf[A-||>nat-{0}](multirel1(A, r))"
   863 apply (case_tac "A=0")
   863 apply (case_tac "A=0")
   864 apply (simp (no_asm_simp))
   864 apply (simp (no_asm_simp))
   865 apply (rule wf_imp_wf_on)
   865 apply (rule wf_imp_wf_on)
   866 apply (rule wf_on_field_imp_wf)
   866 apply (rule wf_on_field_imp_wf)
   867 apply (simp (no_asm_simp) add: wf_on_0)
   867 apply (simp (no_asm_simp) add: wf_on_0)
   868 apply (rule_tac A = "acc (multirel1 (A,r))" in wf_on_subset_A)
   868 apply (rule_tac A = "acc (multirel1 (A,r))" in wf_on_subset_A)
   869 apply (rule wf_on_acc)
   869 apply (rule wf_on_acc)
   870 apply (blast intro: all_accessible)
   870 apply (blast intro: all_accessible)
   871 done
   871 done
   872 
   872 
   873 lemma wf_multirel1: "wf(r) ==>wf(multirel1(field(r), r))"
   873 lemma wf_multirel1: "wf(r) \<Longrightarrow>wf(multirel1(field(r), r))"
   874 apply (simp (no_asm_use) add: wf_iff_wf_on_field)
   874 apply (simp (no_asm_use) add: wf_iff_wf_on_field)
   875 apply (drule wf_on_multirel1)
   875 apply (drule wf_on_multirel1)
   876 apply (rule_tac A = "field (r) -||> nat - {0}" in wf_on_subset_A)
   876 apply (rule_tac A = "field (r) -||> nat - {0}" in wf_on_subset_A)
   877 apply (simp (no_asm_simp))
   877 apply (simp (no_asm_simp))
   878 apply (rule field_rel_subset)
   878 apply (rule field_rel_subset)
   887 apply (auto dest: multirel1_type [THEN subsetD])
   887 apply (auto dest: multirel1_type [THEN subsetD])
   888 done
   888 done
   889 
   889 
   890 (* Monotonicity of multirel *)
   890 (* Monotonicity of multirel *)
   891 lemma multirel_mono:
   891 lemma multirel_mono:
   892      "[| A\<subseteq>B; r\<subseteq>s |] ==> multirel(A, r)\<subseteq>multirel(B,s)"
   892      "\<lbrakk>A\<subseteq>B; r\<subseteq>s\<rbrakk> \<Longrightarrow> multirel(A, r)\<subseteq>multirel(B,s)"
   893 apply (simp add: multirel_def)
   893 apply (simp add: multirel_def)
   894 apply (rule trancl_mono)
   894 apply (rule trancl_mono)
   895 apply (rule multirel1_mono, auto)
   895 apply (rule multirel1_mono, auto)
   896 done
   896 done
   897 
   897 
   898 (* Equivalence of multirel with the usual (closure-free) definition *)
   898 (* Equivalence of multirel with the usual (closure-free) definition *)
   899 
   899 
   900 lemma add_diff_eq: "k \<in> nat ==> 0 < k \<longrightarrow> n #+ k #- 1 = n #+ (k #- 1)"
   900 lemma add_diff_eq: "k \<in> nat \<Longrightarrow> 0 < k \<longrightarrow> n #+ k #- 1 = n #+ (k #- 1)"
   901 by (erule nat_induct, auto)
   901 by (erule nat_induct, auto)
   902 
   902 
   903 lemma mdiff_union_single_conv: "[|a \<in> mset_of(J); multiset(I); multiset(J) |]
   903 lemma mdiff_union_single_conv: "\<lbrakk>a \<in> mset_of(J); multiset(I); multiset(J)\<rbrakk>
   904    ==> I +# J -# {#a#} = I +# (J-# {#a#})"
   904    \<Longrightarrow> I +# J -# {#a#} = I +# (J-# {#a#})"
   905 apply (simp (no_asm_simp) add: multiset_equality)
   905 apply (simp (no_asm_simp) add: multiset_equality)
   906 apply (case_tac "a \<notin> mset_of (I) ")
   906 apply (case_tac "a \<notin> mset_of (I) ")
   907 apply (auto simp add: mcount_def mset_of_def multiset_def multiset_fun_iff)
   907 apply (auto simp add: mcount_def mset_of_def multiset_def multiset_fun_iff)
   908 apply (auto dest: domain_type simp add: add_diff_eq)
   908 apply (auto dest: domain_type simp add: add_diff_eq)
   909 done
   909 done
   910 
   910 
   911 lemma diff_add_commute: "[| n \<le> m;  m \<in> nat; n \<in> nat; k \<in> nat |] ==> m #- n #+ k = m #+ k #- n"
   911 lemma diff_add_commute: "\<lbrakk>n \<le> m;  m \<in> nat; n \<in> nat; k \<in> nat\<rbrakk> \<Longrightarrow> m #- n #+ k = m #+ k #- n"
   912 by (auto simp add: le_iff less_iff_succ_add)
   912 by (auto simp add: le_iff less_iff_succ_add)
   913 
   913 
   914 (* One direction *)
   914 (* One direction *)
   915 
   915 
   916 lemma multirel_implies_one_step:
   916 lemma multirel_implies_one_step:
   917 "<M,N> \<in> multirel(A, r) ==>
   917 "<M,N> \<in> multirel(A, r) \<Longrightarrow>
   918      trans[A](r) \<longrightarrow>
   918      trans[A](r) \<longrightarrow>
   919      (\<exists>I J K.
   919      (\<exists>I J K.
   920          I \<in> Mult(A) & J \<in> Mult(A) &  K \<in> Mult(A) &
   920          I \<in> Mult(A) & J \<in> Mult(A) &  K \<in> Mult(A) &
   921          N = I +# J & M = I +# K & J \<noteq> 0 &
   921          N = I +# J & M = I +# K & J \<noteq> 0 &
   922         (\<forall>k \<in> mset_of(K). \<exists>j \<in> mset_of(J). <k,j> \<in> r))"
   922         (\<forall>k \<in> mset_of(K). \<exists>j \<in> mset_of(J). <k,j> \<in> r))"
   962 apply (auto intro: mcount_elem)
   962 apply (auto intro: mcount_elem)
   963 apply (subgoal_tac "a \<in> mset_of (I +# Ka) ")
   963 apply (subgoal_tac "a \<in> mset_of (I +# Ka) ")
   964 apply (drule_tac [2] sym, auto)
   964 apply (drule_tac [2] sym, auto)
   965 done
   965 done
   966 
   966 
   967 lemma melem_imp_eq_diff_union [simp]: "[| a \<in> mset_of(M); multiset(M) |] ==> M -# {#a#} +# {#a#} = M"
   967 lemma melem_imp_eq_diff_union [simp]: "\<lbrakk>a \<in> mset_of(M); multiset(M)\<rbrakk> \<Longrightarrow> M -# {#a#} +# {#a#} = M"
   968 by (simp add: multiset_equality mcount_elem [THEN succ_pred_eq_self])
   968 by (simp add: multiset_equality mcount_elem [THEN succ_pred_eq_self])
   969 
   969 
   970 lemma msize_eq_succ_imp_eq_union:
   970 lemma msize_eq_succ_imp_eq_union:
   971      "[| msize(M)=$# succ(n); M \<in> Mult(A); n \<in> nat |]
   971      "\<lbrakk>msize(M)=$# succ(n); M \<in> Mult(A); n \<in> nat\<rbrakk>
   972       ==> \<exists>a N. M = N +# {#a#} & N \<in> Mult(A) & a \<in> A"
   972       \<Longrightarrow> \<exists>a N. M = N +# {#a#} & N \<in> Mult(A) & a \<in> A"
   973 apply (drule msize_eq_succ_imp_elem, auto)
   973 apply (drule msize_eq_succ_imp_elem, auto)
   974 apply (rule_tac x = a in exI)
   974 apply (rule_tac x = a in exI)
   975 apply (rule_tac x = "M -# {#a#}" in exI)
   975 apply (rule_tac x = "M -# {#a#}" in exI)
   976 apply (frule Mult_into_multiset)
   976 apply (frule Mult_into_multiset)
   977 apply (simp (no_asm_simp))
   977 apply (simp (no_asm_simp))
   979 done
   979 done
   980 
   980 
   981 (* The second direction *)
   981 (* The second direction *)
   982 
   982 
   983 lemma one_step_implies_multirel_lemma [rule_format (no_asm)]:
   983 lemma one_step_implies_multirel_lemma [rule_format (no_asm)]:
   984 "n \<in> nat ==>
   984 "n \<in> nat \<Longrightarrow>
   985    (\<forall>I J K.
   985    (\<forall>I J K.
   986     I \<in> Mult(A) & J \<in> Mult(A) & K \<in> Mult(A) &
   986     I \<in> Mult(A) & J \<in> Mult(A) & K \<in> Mult(A) &
   987    (msize(J) = $# n & J \<noteq>0 &  (\<forall>k \<in> mset_of(K).  \<exists>j \<in> mset_of(J). <k, j> \<in> r))
   987    (msize(J) = $# n & J \<noteq>0 &  (\<forall>k \<in> mset_of(K).  \<exists>j \<in> mset_of(J). <k, j> \<in> r))
   988     \<longrightarrow> <I +# K, I +# J> \<in> multirel(A, r))"
   988     \<longrightarrow> <I +# K, I +# J> \<in> multirel(A, r))"
   989 apply (simp add: Mult_iff_multiset)
   989 apply (simp add: Mult_iff_multiset)
  1022 apply (rule_tac x = "I +# J'" in exI)
  1022 apply (rule_tac x = "I +# J'" in exI)
  1023 apply (auto simp add: munion_ac Un_subset_iff)
  1023 apply (auto simp add: munion_ac Un_subset_iff)
  1024 done
  1024 done
  1025 
  1025 
  1026 lemma one_step_implies_multirel:
  1026 lemma one_step_implies_multirel:
  1027      "[| J \<noteq> 0;  \<forall>k \<in> mset_of(K). \<exists>j \<in> mset_of(J). <k,j> \<in> r;
  1027      "\<lbrakk>J \<noteq> 0;  \<forall>k \<in> mset_of(K). \<exists>j \<in> mset_of(J). <k,j> \<in> r;
  1028          I \<in> Mult(A); J \<in> Mult(A); K \<in> Mult(A) |]
  1028          I \<in> Mult(A); J \<in> Mult(A); K \<in> Mult(A)\<rbrakk>
  1029       ==> <I+#K, I+#J> \<in> multirel(A, r)"
  1029       \<Longrightarrow> <I+#K, I+#J> \<in> multirel(A, r)"
  1030 apply (subgoal_tac "multiset (J) ")
  1030 apply (subgoal_tac "multiset (J) ")
  1031  prefer 2 apply (simp add: Mult_iff_multiset)
  1031  prefer 2 apply (simp add: Mult_iff_multiset)
  1032 apply (frule_tac M = J in msize_int_of_nat)
  1032 apply (frule_tac M = J in msize_int_of_nat)
  1033 apply (auto intro: one_step_implies_multirel_lemma)
  1033 apply (auto intro: one_step_implies_multirel_lemma)
  1034 done
  1034 done
  1036 (** Proving that multisets are partially ordered **)
  1036 (** Proving that multisets are partially ordered **)
  1037 
  1037 
  1038 (*irreflexivity*)
  1038 (*irreflexivity*)
  1039 
  1039 
  1040 lemma multirel_irrefl_lemma:
  1040 lemma multirel_irrefl_lemma:
  1041      "Finite(A) ==> part_ord(A, r) \<longrightarrow> (\<forall>x \<in> A. \<exists>y \<in> A. <x,y> \<in> r) \<longrightarrow>A=0"
  1041      "Finite(A) \<Longrightarrow> part_ord(A, r) \<longrightarrow> (\<forall>x \<in> A. \<exists>y \<in> A. <x,y> \<in> r) \<longrightarrow>A=0"
  1042 apply (erule Finite_induct)
  1042 apply (erule Finite_induct)
  1043 apply (auto dest: subset_consI [THEN [2] part_ord_subset])
  1043 apply (auto dest: subset_consI [THEN [2] part_ord_subset])
  1044 apply (auto simp add: part_ord_def irrefl_def)
  1044 apply (auto simp add: part_ord_def irrefl_def)
  1045 apply (drule_tac x = xa in bspec)
  1045 apply (drule_tac x = xa in bspec)
  1046 apply (drule_tac [2] a = xa and b = x in trans_onD, auto)
  1046 apply (drule_tac [2] a = xa and b = x in trans_onD, auto)
  1047 done
  1047 done
  1048 
  1048 
  1049 lemma irrefl_on_multirel:
  1049 lemma irrefl_on_multirel:
  1050      "part_ord(A, r) ==> irrefl(Mult(A), multirel(A, r))"
  1050      "part_ord(A, r) \<Longrightarrow> irrefl(Mult(A), multirel(A, r))"
  1051 apply (simp add: irrefl_def)
  1051 apply (simp add: irrefl_def)
  1052 apply (subgoal_tac "trans[A](r) ")
  1052 apply (subgoal_tac "trans[A](r) ")
  1053  prefer 2 apply (simp add: part_ord_def, clarify)
  1053  prefer 2 apply (simp add: part_ord_def, clarify)
  1054 apply (drule multirel_implies_one_step, clarify)
  1054 apply (drule multirel_implies_one_step, clarify)
  1055 apply (simp add: Mult_iff_multiset, clarify)
  1055 apply (simp add: Mult_iff_multiset, clarify)
  1064 apply (simp add: multirel_def trans_on_def)
  1064 apply (simp add: multirel_def trans_on_def)
  1065 apply (blast intro: trancl_trans)
  1065 apply (blast intro: trancl_trans)
  1066 done
  1066 done
  1067 
  1067 
  1068 lemma multirel_trans:
  1068 lemma multirel_trans:
  1069  "[| <M, N> \<in> multirel(A, r); <N, K> \<in> multirel(A, r) |] ==>  <M, K> \<in> multirel(A,r)"
  1069  "\<lbrakk><M, N> \<in> multirel(A, r); <N, K> \<in> multirel(A, r)\<rbrakk> \<Longrightarrow>  <M, K> \<in> multirel(A,r)"
  1070 apply (simp add: multirel_def)
  1070 apply (simp add: multirel_def)
  1071 apply (blast intro: trancl_trans)
  1071 apply (blast intro: trancl_trans)
  1072 done
  1072 done
  1073 
  1073 
  1074 lemma trans_multirel: "trans(multirel(A,r))"
  1074 lemma trans_multirel: "trans(multirel(A,r))"
  1075 apply (simp add: multirel_def)
  1075 apply (simp add: multirel_def)
  1076 apply (rule trans_trancl)
  1076 apply (rule trans_trancl)
  1077 done
  1077 done
  1078 
  1078 
  1079 lemma part_ord_multirel: "part_ord(A,r) ==> part_ord(Mult(A), multirel(A, r))"
  1079 lemma part_ord_multirel: "part_ord(A,r) \<Longrightarrow> part_ord(Mult(A), multirel(A, r))"
  1080 apply (simp (no_asm) add: part_ord_def)
  1080 apply (simp (no_asm) add: part_ord_def)
  1081 apply (blast intro: irrefl_on_multirel trans_on_multirel)
  1081 apply (blast intro: irrefl_on_multirel trans_on_multirel)
  1082 done
  1082 done
  1083 
  1083 
  1084 (** Monotonicity of multiset union **)
  1084 (** Monotonicity of multiset union **)
  1085 
  1085 
  1086 lemma munion_multirel1_mono:
  1086 lemma munion_multirel1_mono:
  1087 "[|<M,N> \<in> multirel1(A, r); K \<in> Mult(A) |] ==> <K +# M, K +# N> \<in> multirel1(A, r)"
  1087 "\<lbrakk><M,N> \<in> multirel1(A, r); K \<in> Mult(A)\<rbrakk> \<Longrightarrow> <K +# M, K +# N> \<in> multirel1(A, r)"
  1088 apply (frule multirel1_type [THEN subsetD])
  1088 apply (frule multirel1_type [THEN subsetD])
  1089 apply (auto simp add: multirel1_iff Mult_iff_multiset)
  1089 apply (auto simp add: multirel1_iff Mult_iff_multiset)
  1090 apply (rule_tac x = a in exI)
  1090 apply (rule_tac x = a in exI)
  1091 apply (simp (no_asm_simp))
  1091 apply (simp (no_asm_simp))
  1092 apply (rule_tac x = "K+#M0" in exI)
  1092 apply (rule_tac x = "K+#M0" in exI)
  1094 apply (rule_tac x = Ka in exI)
  1094 apply (rule_tac x = Ka in exI)
  1095 apply (simp (no_asm_simp) add: munion_assoc)
  1095 apply (simp (no_asm_simp) add: munion_assoc)
  1096 done
  1096 done
  1097 
  1097 
  1098 lemma munion_multirel_mono2:
  1098 lemma munion_multirel_mono2:
  1099  "[| <M, N> \<in> multirel(A, r); K \<in> Mult(A) |]==><K +# M, K +# N> \<in> multirel(A, r)"
  1099  "\<lbrakk><M, N> \<in> multirel(A, r); K \<in> Mult(A)\<rbrakk>\<Longrightarrow><K +# M, K +# N> \<in> multirel(A, r)"
  1100 apply (frule multirel_type [THEN subsetD])
  1100 apply (frule multirel_type [THEN subsetD])
  1101 apply (simp (no_asm_use) add: multirel_def)
  1101 apply (simp (no_asm_use) add: multirel_def)
  1102 apply clarify
  1102 apply clarify
  1103 apply (drule_tac psi = "<M,N> \<in> multirel1 (A, r) ^+" in asm_rl)
  1103 apply (drule_tac psi = "<M,N> \<in> multirel1 (A, r) ^+" in asm_rl)
  1104 apply (erule rev_mp)
  1104 apply (erule rev_mp)
  1113 prefer 2 apply (blast intro: munion_multirel1_mono)
  1113 prefer 2 apply (blast intro: munion_multirel1_mono)
  1114 apply (blast intro: r_into_trancl trancl_trans)
  1114 apply (blast intro: r_into_trancl trancl_trans)
  1115 done
  1115 done
  1116 
  1116 
  1117 lemma munion_multirel_mono1:
  1117 lemma munion_multirel_mono1:
  1118      "[|<M, N> \<in> multirel(A, r); K \<in> Mult(A)|] ==> <M +# K, N +# K> \<in> multirel(A, r)"
  1118      "\<lbrakk><M, N> \<in> multirel(A, r); K \<in> Mult(A)\<rbrakk> \<Longrightarrow> <M +# K, N +# K> \<in> multirel(A, r)"
  1119 apply (frule multirel_type [THEN subsetD])
  1119 apply (frule multirel_type [THEN subsetD])
  1120 apply (rule_tac P = "%x. <x,u> \<in> multirel(A, r)" for u in munion_commute [THEN subst])
  1120 apply (rule_tac P = "%x. <x,u> \<in> multirel(A, r)" for u in munion_commute [THEN subst])
  1121 apply (subst munion_commute [of N])
  1121 apply (subst munion_commute [of N])
  1122 apply (rule munion_multirel_mono2)
  1122 apply (rule munion_multirel_mono2)
  1123 apply (auto simp add: Mult_iff_multiset)
  1123 apply (auto simp add: Mult_iff_multiset)
  1124 done
  1124 done
  1125 
  1125 
  1126 lemma munion_multirel_mono:
  1126 lemma munion_multirel_mono:
  1127      "[|<M,K> \<in> multirel(A, r); <N,L> \<in> multirel(A, r)|]
  1127      "\<lbrakk><M,K> \<in> multirel(A, r); <N,L> \<in> multirel(A, r)\<rbrakk>
  1128       ==> <M +# N, K +# L> \<in> multirel(A, r)"
  1128       \<Longrightarrow> <M +# N, K +# L> \<in> multirel(A, r)"
  1129 apply (subgoal_tac "M \<in> Mult(A) & N \<in> Mult(A) & K \<in> Mult(A) & L \<in> Mult(A) ")
  1129 apply (subgoal_tac "M \<in> Mult(A) & N \<in> Mult(A) & K \<in> Mult(A) & L \<in> Mult(A) ")
  1130 prefer 2 apply (blast dest: multirel_type [THEN subsetD])
  1130 prefer 2 apply (blast dest: multirel_type [THEN subsetD])
  1131 apply (blast intro: munion_multirel_mono1 multirel_trans munion_multirel_mono2)
  1131 apply (blast intro: munion_multirel_mono1 multirel_trans munion_multirel_mono2)
  1132 done
  1132 done
  1133 
  1133 
  1134 
  1134 
  1135 subsection\<open>Ordinal Multisets\<close>
  1135 subsection\<open>Ordinal Multisets\<close>
  1136 
  1136 
  1137 (* A \<subseteq> B ==>  field(Memrel(A)) \<subseteq> field(Memrel(B)) *)
  1137 (* A \<subseteq> B \<Longrightarrow>  field(Memrel(A)) \<subseteq> field(Memrel(B)) *)
  1138 lemmas field_Memrel_mono = Memrel_mono [THEN field_mono]
  1138 lemmas field_Memrel_mono = Memrel_mono [THEN field_mono]
  1139 
  1139 
  1140 (*
  1140 (*
  1141 [| Aa \<subseteq> Ba; A \<subseteq> B |] ==>
  1141 \<lbrakk>Aa \<subseteq> Ba; A \<subseteq> B\<rbrakk> \<Longrightarrow>
  1142 multirel(field(Memrel(Aa)), Memrel(A))\<subseteq> multirel(field(Memrel(Ba)), Memrel(B))
  1142 multirel(field(Memrel(Aa)), Memrel(A))\<subseteq> multirel(field(Memrel(Ba)), Memrel(B))
  1143 *)
  1143 *)
  1144 
  1144 
  1145 lemmas multirel_Memrel_mono = multirel_mono [OF field_Memrel_mono Memrel_mono]
  1145 lemmas multirel_Memrel_mono = multirel_mono [OF field_Memrel_mono Memrel_mono]
  1146 
  1146 
  1147 lemma omultiset_is_multiset [simp]: "omultiset(M) ==> multiset(M)"
  1147 lemma omultiset_is_multiset [simp]: "omultiset(M) \<Longrightarrow> multiset(M)"
  1148 apply (simp add: omultiset_def)
  1148 apply (simp add: omultiset_def)
  1149 apply (auto simp add: Mult_iff_multiset)
  1149 apply (auto simp add: Mult_iff_multiset)
  1150 done
  1150 done
  1151 
  1151 
  1152 lemma munion_omultiset [simp]: "[| omultiset(M); omultiset(N) |] ==> omultiset(M +# N)"
  1152 lemma munion_omultiset [simp]: "\<lbrakk>omultiset(M); omultiset(N)\<rbrakk> \<Longrightarrow> omultiset(M +# N)"
  1153 apply (simp add: omultiset_def, clarify)
  1153 apply (simp add: omultiset_def, clarify)
  1154 apply (rule_tac x = "i \<union> ia" in exI)
  1154 apply (rule_tac x = "i \<union> ia" in exI)
  1155 apply (simp add: Mult_iff_multiset Ord_Un Un_subset_iff)
  1155 apply (simp add: Mult_iff_multiset Ord_Un Un_subset_iff)
  1156 apply (blast intro: field_Memrel_mono)
  1156 apply (blast intro: field_Memrel_mono)
  1157 done
  1157 done
  1158 
  1158 
  1159 lemma mdiff_omultiset [simp]: "omultiset(M) ==> omultiset(M -# N)"
  1159 lemma mdiff_omultiset [simp]: "omultiset(M) \<Longrightarrow> omultiset(M -# N)"
  1160 apply (simp add: omultiset_def, clarify)
  1160 apply (simp add: omultiset_def, clarify)
  1161 apply (simp add: Mult_iff_multiset)
  1161 apply (simp add: Mult_iff_multiset)
  1162 apply (rule_tac x = i in exI)
  1162 apply (rule_tac x = i in exI)
  1163 apply (simp (no_asm_simp))
  1163 apply (simp (no_asm_simp))
  1164 done
  1164 done
  1165 
  1165 
  1166 (** Proving that Memrel is a partial order **)
  1166 (** Proving that Memrel is a partial order **)
  1167 
  1167 
  1168 lemma irrefl_Memrel: "Ord(i) ==> irrefl(field(Memrel(i)), Memrel(i))"
  1168 lemma irrefl_Memrel: "Ord(i) \<Longrightarrow> irrefl(field(Memrel(i)), Memrel(i))"
  1169 apply (rule irreflI, clarify)
  1169 apply (rule irreflI, clarify)
  1170 apply (subgoal_tac "Ord (x) ")
  1170 apply (subgoal_tac "Ord (x) ")
  1171 prefer 2 apply (blast intro: Ord_in_Ord)
  1171 prefer 2 apply (blast intro: Ord_in_Ord)
  1172 apply (drule_tac i = x in ltI [THEN lt_irrefl], auto)
  1172 apply (drule_tac i = x in ltI [THEN lt_irrefl], auto)
  1173 done
  1173 done
  1174 
  1174 
  1175 lemma trans_iff_trans_on: "trans(r) \<longleftrightarrow> trans[field(r)](r)"
  1175 lemma trans_iff_trans_on: "trans(r) \<longleftrightarrow> trans[field(r)](r)"
  1176 by (simp add: trans_on_def trans_def, auto)
  1176 by (simp add: trans_on_def trans_def, auto)
  1177 
  1177 
  1178 lemma part_ord_Memrel: "Ord(i) ==>part_ord(field(Memrel(i)), Memrel(i))"
  1178 lemma part_ord_Memrel: "Ord(i) \<Longrightarrow>part_ord(field(Memrel(i)), Memrel(i))"
  1179 apply (simp add: part_ord_def)
  1179 apply (simp add: part_ord_def)
  1180 apply (simp (no_asm) add: trans_iff_trans_on [THEN iff_sym])
  1180 apply (simp (no_asm) add: trans_iff_trans_on [THEN iff_sym])
  1181 apply (blast intro: trans_Memrel irrefl_Memrel)
  1181 apply (blast intro: trans_Memrel irrefl_Memrel)
  1182 done
  1182 done
  1183 
  1183 
  1184 (*
  1184 (*
  1185   Ord(i) ==>
  1185   Ord(i) \<Longrightarrow>
  1186   part_ord(field(Memrel(i))-||>nat-{0}, multirel(field(Memrel(i)), Memrel(i)))
  1186   part_ord(field(Memrel(i))-||>nat-{0}, multirel(field(Memrel(i)), Memrel(i)))
  1187 *)
  1187 *)
  1188 
  1188 
  1189 lemmas part_ord_mless = part_ord_Memrel [THEN part_ord_multirel]
  1189 lemmas part_ord_mless = part_ord_Memrel [THEN part_ord_multirel]
  1190 
  1190 
  1191 (*irreflexivity*)
  1191 (*irreflexivity*)
  1192 
  1192 
  1193 lemma mless_not_refl: "~(M <# M)"
  1193 lemma mless_not_refl: "\<not>(M <# M)"
  1194 apply (simp add: mless_def, clarify)
  1194 apply (simp add: mless_def, clarify)
  1195 apply (frule multirel_type [THEN subsetD])
  1195 apply (frule multirel_type [THEN subsetD])
  1196 apply (drule part_ord_mless)
  1196 apply (drule part_ord_mless)
  1197 apply (simp add: part_ord_def irrefl_def)
  1197 apply (simp add: part_ord_def irrefl_def)
  1198 done
  1198 done
  1199 
  1199 
  1200 (* N<N ==> R *)
  1200 (* N<N \<Longrightarrow> R *)
  1201 lemmas mless_irrefl = mless_not_refl [THEN notE, elim!]
  1201 lemmas mless_irrefl = mless_not_refl [THEN notE, elim!]
  1202 
  1202 
  1203 (*transitivity*)
  1203 (*transitivity*)
  1204 lemma mless_trans: "[| K <# M; M <# N |] ==> K <# N"
  1204 lemma mless_trans: "\<lbrakk>K <# M; M <# N\<rbrakk> \<Longrightarrow> K <# N"
  1205 apply (simp add: mless_def, clarify)
  1205 apply (simp add: mless_def, clarify)
  1206 apply (rule_tac x = "i \<union> ia" in exI)
  1206 apply (rule_tac x = "i \<union> ia" in exI)
  1207 apply (blast dest: multirel_Memrel_mono [OF Un_upper1 Un_upper1, THEN subsetD]
  1207 apply (blast dest: multirel_Memrel_mono [OF Un_upper1 Un_upper1, THEN subsetD]
  1208                    multirel_Memrel_mono [OF Un_upper2 Un_upper2, THEN subsetD]
  1208                    multirel_Memrel_mono [OF Un_upper2 Un_upper2, THEN subsetD]
  1209         intro: multirel_trans Ord_Un)
  1209         intro: multirel_trans Ord_Un)
  1210 done
  1210 done
  1211 
  1211 
  1212 (*asymmetry*)
  1212 (*asymmetry*)
  1213 lemma mless_not_sym: "M <# N ==> ~ N <# M"
  1213 lemma mless_not_sym: "M <# N \<Longrightarrow> \<not> N <# M"
  1214 apply clarify
  1214 apply clarify
  1215 apply (rule mless_not_refl [THEN notE])
  1215 apply (rule mless_not_refl [THEN notE])
  1216 apply (erule mless_trans, assumption)
  1216 apply (erule mless_trans, assumption)
  1217 done
  1217 done
  1218 
  1218 
  1219 lemma mless_asym: "[| M <# N; ~P ==> N <# M |] ==> P"
  1219 lemma mless_asym: "\<lbrakk>M <# N; \<not>P \<Longrightarrow> N <# M\<rbrakk> \<Longrightarrow> P"
  1220 by (blast dest: mless_not_sym)
  1220 by (blast dest: mless_not_sym)
  1221 
  1221 
  1222 lemma mle_refl [simp]: "omultiset(M) ==> M <#= M"
  1222 lemma mle_refl [simp]: "omultiset(M) \<Longrightarrow> M <#= M"
  1223 by (simp add: mle_def)
  1223 by (simp add: mle_def)
  1224 
  1224 
  1225 (*anti-symmetry*)
  1225 (*anti-symmetry*)
  1226 lemma mle_antisym:
  1226 lemma mle_antisym:
  1227      "[| M <#= N;  N <#= M |] ==> M = N"
  1227      "\<lbrakk>M <#= N;  N <#= M\<rbrakk> \<Longrightarrow> M = N"
  1228 apply (simp add: mle_def)
  1228 apply (simp add: mle_def)
  1229 apply (blast dest: mless_not_sym)
  1229 apply (blast dest: mless_not_sym)
  1230 done
  1230 done
  1231 
  1231 
  1232 (*transitivity*)
  1232 (*transitivity*)
  1233 lemma mle_trans: "[| K <#= M; M <#= N |] ==> K <#= N"
  1233 lemma mle_trans: "\<lbrakk>K <#= M; M <#= N\<rbrakk> \<Longrightarrow> K <#= N"
  1234 apply (simp add: mle_def)
  1234 apply (simp add: mle_def)
  1235 apply (blast intro: mless_trans)
  1235 apply (blast intro: mless_trans)
  1236 done
  1236 done
  1237 
  1237 
  1238 lemma mless_le_iff: "M <# N \<longleftrightarrow> (M <#= N & M \<noteq> N)"
  1238 lemma mless_le_iff: "M <# N \<longleftrightarrow> (M <#= N & M \<noteq> N)"
  1239 by (simp add: mle_def, auto)
  1239 by (simp add: mle_def, auto)
  1240 
  1240 
  1241 (** Monotonicity of mless **)
  1241 (** Monotonicity of mless **)
  1242 
  1242 
  1243 lemma munion_less_mono2: "[| M <# N; omultiset(K) |] ==> K +# M <# K +# N"
  1243 lemma munion_less_mono2: "\<lbrakk>M <# N; omultiset(K)\<rbrakk> \<Longrightarrow> K +# M <# K +# N"
  1244 apply (simp add: mless_def omultiset_def, clarify)
  1244 apply (simp add: mless_def omultiset_def, clarify)
  1245 apply (rule_tac x = "i \<union> ia" in exI)
  1245 apply (rule_tac x = "i \<union> ia" in exI)
  1246 apply (simp add: Mult_iff_multiset Ord_Un Un_subset_iff)
  1246 apply (simp add: Mult_iff_multiset Ord_Un Un_subset_iff)
  1247 apply (rule munion_multirel_mono2)
  1247 apply (rule munion_multirel_mono2)
  1248  apply (blast intro: multirel_Memrel_mono [THEN subsetD])
  1248  apply (blast intro: multirel_Memrel_mono [THEN subsetD])
  1249 apply (simp add: Mult_iff_multiset)
  1249 apply (simp add: Mult_iff_multiset)
  1250 apply (blast intro: field_Memrel_mono [THEN subsetD])
  1250 apply (blast intro: field_Memrel_mono [THEN subsetD])
  1251 done
  1251 done
  1252 
  1252 
  1253 lemma munion_less_mono1: "[| M <# N; omultiset(K) |] ==> M +# K <# N +# K"
  1253 lemma munion_less_mono1: "\<lbrakk>M <# N; omultiset(K)\<rbrakk> \<Longrightarrow> M +# K <# N +# K"
  1254 by (force dest: munion_less_mono2 simp add: munion_commute)
  1254 by (force dest: munion_less_mono2 simp add: munion_commute)
  1255 
  1255 
  1256 lemma mless_imp_omultiset: "M <# N ==> omultiset(M) & omultiset(N)"
  1256 lemma mless_imp_omultiset: "M <# N \<Longrightarrow> omultiset(M) & omultiset(N)"
  1257 by (auto simp add: mless_def omultiset_def dest: multirel_type [THEN subsetD])
  1257 by (auto simp add: mless_def omultiset_def dest: multirel_type [THEN subsetD])
  1258 
  1258 
  1259 lemma munion_less_mono: "[| M <# K; N <# L |] ==> M +# N <# K +# L"
  1259 lemma munion_less_mono: "\<lbrakk>M <# K; N <# L\<rbrakk> \<Longrightarrow> M +# N <# K +# L"
  1260 apply (frule_tac M = M in mless_imp_omultiset)
  1260 apply (frule_tac M = M in mless_imp_omultiset)
  1261 apply (frule_tac M = N in mless_imp_omultiset)
  1261 apply (frule_tac M = N in mless_imp_omultiset)
  1262 apply (blast intro: munion_less_mono1 munion_less_mono2 mless_trans)
  1262 apply (blast intro: munion_less_mono1 munion_less_mono2 mless_trans)
  1263 done
  1263 done
  1264 
  1264 
  1265 (* <#= *)
  1265 (* <#= *)
  1266 
  1266 
  1267 lemma mle_imp_omultiset: "M <#= N ==> omultiset(M) & omultiset(N)"
  1267 lemma mle_imp_omultiset: "M <#= N \<Longrightarrow> omultiset(M) & omultiset(N)"
  1268 by (auto simp add: mle_def mless_imp_omultiset)
  1268 by (auto simp add: mle_def mless_imp_omultiset)
  1269 
  1269 
  1270 lemma mle_mono: "[| M <#= K;  N <#= L |] ==> M +# N <#= K +# L"
  1270 lemma mle_mono: "\<lbrakk>M <#= K;  N <#= L\<rbrakk> \<Longrightarrow> M +# N <#= K +# L"
  1271 apply (frule_tac M = M in mle_imp_omultiset)
  1271 apply (frule_tac M = M in mle_imp_omultiset)
  1272 apply (frule_tac M = N in mle_imp_omultiset)
  1272 apply (frule_tac M = N in mle_imp_omultiset)
  1273 apply (auto simp add: mle_def intro: munion_less_mono1 munion_less_mono2 munion_less_mono)
  1273 apply (auto simp add: mle_def intro: munion_less_mono1 munion_less_mono2 munion_less_mono)
  1274 done
  1274 done
  1275 
  1275 
  1276 lemma omultiset_0 [iff]: "omultiset(0)"
  1276 lemma omultiset_0 [iff]: "omultiset(0)"
  1277 by (auto simp add: omultiset_def Mult_iff_multiset)
  1277 by (auto simp add: omultiset_def Mult_iff_multiset)
  1278 
  1278 
  1279 lemma empty_leI [simp]: "omultiset(M) ==> 0 <#= M"
  1279 lemma empty_leI [simp]: "omultiset(M) \<Longrightarrow> 0 <#= M"
  1280 apply (simp add: mle_def mless_def)
  1280 apply (simp add: mle_def mless_def)
  1281 apply (subgoal_tac "\<exists>i. Ord (i) & M \<in> Mult(field(Memrel(i))) ")
  1281 apply (subgoal_tac "\<exists>i. Ord (i) & M \<in> Mult(field(Memrel(i))) ")
  1282  prefer 2 apply (simp add: omultiset_def)
  1282  prefer 2 apply (simp add: omultiset_def)
  1283 apply (case_tac "M=0", simp_all, clarify)
  1283 apply (case_tac "M=0", simp_all, clarify)
  1284 apply (subgoal_tac "<0 +# 0, 0 +# M> \<in> multirel(field (Memrel(i)), Memrel(i))")
  1284 apply (subgoal_tac "<0 +# 0, 0 +# M> \<in> multirel(field (Memrel(i)), Memrel(i))")
  1285 apply (rule_tac [2] one_step_implies_multirel)
  1285 apply (rule_tac [2] one_step_implies_multirel)
  1286 apply (auto simp add: Mult_iff_multiset)
  1286 apply (auto simp add: Mult_iff_multiset)
  1287 done
  1287 done
  1288 
  1288 
  1289 lemma munion_upper1: "[| omultiset(M); omultiset(N) |] ==> M <#= M +# N"
  1289 lemma munion_upper1: "\<lbrakk>omultiset(M); omultiset(N)\<rbrakk> \<Longrightarrow> M <#= M +# N"
  1290 apply (subgoal_tac "M +# 0 <#= M +# N")
  1290 apply (subgoal_tac "M +# 0 <#= M +# N")
  1291 apply (rule_tac [2] mle_mono, auto)
  1291 apply (rule_tac [2] mle_mono, auto)
  1292 done
  1292 done
  1293 
  1293 
  1294 end
  1294 end