520 supseteq_mset (infix ">=#" 50) and |
520 supseteq_mset (infix ">=#" 50) and |
521 supset_mset (infix ">#" 50) |
521 supset_mset (infix ">#" 50) |
522 |
522 |
523 interpretation subset_mset: ordered_ab_semigroup_add_imp_le "op +" "op -" "op \<subseteq>#" "op \<subset>#" |
523 interpretation subset_mset: ordered_ab_semigroup_add_imp_le "op +" "op -" "op \<subseteq>#" "op \<subset>#" |
524 by standard (auto simp add: subset_mset_def subseteq_mset_def multiset_eq_iff intro: order_trans antisym) |
524 by standard (auto simp add: subset_mset_def subseteq_mset_def multiset_eq_iff intro: order_trans antisym) |
525 \<comment> \<open>FIXME: avoid junk stemming from type class interpretation\<close> |
|
526 |
525 |
527 interpretation subset_mset: ordered_ab_semigroup_monoid_add_imp_le "op +" 0 "op -" "op \<le>#" "op <#" |
526 interpretation subset_mset: ordered_ab_semigroup_monoid_add_imp_le "op +" 0 "op -" "op \<le>#" "op <#" |
528 by standard |
527 by standard |
529 |
528 |
530 lemma mset_subset_eqI: |
529 lemma mset_subset_eqI: |
642 |
641 |
643 lemma subset_eq_diff_conv: |
642 lemma subset_eq_diff_conv: |
644 "A - C \<subseteq># B \<longleftrightarrow> A \<subseteq># B + C" |
643 "A - C \<subseteq># B \<longleftrightarrow> A \<subseteq># B + C" |
645 by (simp add: subseteq_mset_def le_diff_conv) |
644 by (simp add: subseteq_mset_def le_diff_conv) |
646 |
645 |
647 lemma subset_eq_empty[simp]: "M \<subseteq># {#} \<longleftrightarrow> M = {#}" |
|
648 by auto |
|
649 |
|
650 lemma multi_psub_of_add_self [simp]: "A \<subset># add_mset x A" |
646 lemma multi_psub_of_add_self [simp]: "A \<subset># add_mset x A" |
651 by (auto simp: subset_mset_def subseteq_mset_def) |
647 by (auto simp: subset_mset_def subseteq_mset_def) |
652 |
648 |
653 lemma multi_psub_self[simp]: "(A::'a multiset) \<subset># A = False" |
649 lemma multi_psub_self: "A \<subset># A = False" |
654 by simp |
650 by simp |
655 |
651 |
656 lemma mset_subset_add_mset [simp]: "add_mset x N \<subset># add_mset x M \<longleftrightarrow> N \<subset># M" |
652 lemma mset_subset_add_mset [simp]: "add_mset x N \<subset># add_mset x M \<longleftrightarrow> N \<subset># M" |
657 unfolding add_mset_add_single[of _ N] add_mset_add_single[of _ M] |
653 unfolding add_mset_add_single[of _ N] add_mset_add_single[of _ M] |
658 by (fact subset_mset.add_less_cancel_right) |
654 by (fact subset_mset.add_less_cancel_right) |
659 |
655 |
660 lemma mset_subset_empty_nonempty: "{#} \<subset># S \<longleftrightarrow> S \<noteq> {#}" |
|
661 by (fact subset_mset.zero_less_iff_neq_zero) |
|
662 |
|
663 lemma mset_subset_diff_self: "c \<in># B \<Longrightarrow> B - {#c#} \<subset># B" |
656 lemma mset_subset_diff_self: "c \<in># B \<Longrightarrow> B - {#c#} \<subset># B" |
664 by (auto simp: subset_mset_def elim: mset_add) |
657 by (auto simp: subset_mset_def elim: mset_add) |
665 |
658 |
666 |
659 |
667 subsubsection \<open>Intersection\<close> |
660 subsubsection \<open>Intersection and bounded union\<close> |
668 |
661 |
669 definition inf_subset_mset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset" (infixl "\<inter>#" 70) where |
662 definition inf_subset_mset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset" (infixl "\<inter>#" 70) where |
670 multiset_inter_def: "inf_subset_mset A B = A - (A - B)" |
663 multiset_inter_def: "inf_subset_mset A B = A - (A - B)" |
671 |
664 |
672 interpretation subset_mset: semilattice_inf inf_subset_mset "op \<subseteq>#" "op \<subset>#" |
665 interpretation subset_mset: semilattice_inf inf_subset_mset "op \<subseteq>#" "op \<subset>#" |
675 by arith |
668 by arith |
676 show "class.semilattice_inf op \<inter># op \<subseteq># op \<subset>#" |
669 show "class.semilattice_inf op \<inter># op \<subseteq># op \<subset>#" |
677 by standard (auto simp add: multiset_inter_def subseteq_mset_def) |
670 by standard (auto simp add: multiset_inter_def subseteq_mset_def) |
678 qed |
671 qed |
679 \<comment> \<open>FIXME: avoid junk stemming from type class interpretation\<close> |
672 \<comment> \<open>FIXME: avoid junk stemming from type class interpretation\<close> |
|
673 |
|
674 definition sup_subset_mset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset"(infixl "\<union>#" 70) |
|
675 where "sup_subset_mset A B = A + (B - A)" \<comment> \<open>FIXME irregular fact name\<close> |
|
676 |
|
677 interpretation subset_mset: semilattice_sup sup_subset_mset "op \<subseteq>#" "op \<subset>#" |
|
678 proof - |
|
679 have [simp]: "m \<le> n \<Longrightarrow> q \<le> n \<Longrightarrow> m + (q - m) \<le> n" for m n q :: nat |
|
680 by arith |
|
681 show "class.semilattice_sup op \<union># op \<subseteq># op \<subset>#" |
|
682 by standard (auto simp add: sup_subset_mset_def subseteq_mset_def) |
|
683 qed |
|
684 \<comment> \<open>FIXME: avoid junk stemming from type class interpretation\<close> |
|
685 |
|
686 interpretation subset_mset: bounded_lattice_bot "op \<inter>#" "op \<subseteq>#" "op \<subset>#" |
|
687 "op \<union>#" "{#}" |
|
688 by standard auto |
|
689 |
|
690 |
|
691 subsubsection \<open>Additional intersection facts\<close> |
680 |
692 |
681 lemma multiset_inter_count [simp]: |
693 lemma multiset_inter_count [simp]: |
682 fixes A B :: "'a multiset" |
694 fixes A B :: "'a multiset" |
683 shows "count (A \<inter># B) x = min (count A x) (count B x)" |
695 shows "count (A \<inter># B) x = min (count A x) (count B x)" |
684 by (simp add: multiset_inter_def) |
696 by (simp add: multiset_inter_def) |
750 lemma disjoint_add_mset [simp]: |
762 lemma disjoint_add_mset [simp]: |
751 "B \<inter># add_mset a A = {#} \<longleftrightarrow> a \<notin># B \<and> B \<inter># A = {#}" |
763 "B \<inter># add_mset a A = {#} \<longleftrightarrow> a \<notin># B \<and> B \<inter># A = {#}" |
752 "{#} = A \<inter># add_mset b B \<longleftrightarrow> b \<notin># A \<and> {#} = A \<inter># B" |
764 "{#} = A \<inter># add_mset b B \<longleftrightarrow> b \<notin># A \<and> {#} = A \<inter># B" |
753 by (auto simp: disjunct_not_in) |
765 by (auto simp: disjunct_not_in) |
754 |
766 |
755 lemma empty_inter[simp]: "{#} \<inter># M = {#}" |
|
756 by (simp add: multiset_eq_iff) |
|
757 |
|
758 lemma inter_empty[simp]: "M \<inter># {#} = {#}" |
|
759 by (simp add: multiset_eq_iff) |
|
760 |
|
761 lemma inter_add_left1: "\<not> x \<in># N \<Longrightarrow> (add_mset x M) \<inter># N = M \<inter># N" |
767 lemma inter_add_left1: "\<not> x \<in># N \<Longrightarrow> (add_mset x M) \<inter># N = M \<inter># N" |
762 by (simp add: multiset_eq_iff not_in_iff) |
768 by (simp add: multiset_eq_iff not_in_iff) |
763 |
769 |
764 lemma inter_add_left2: "x \<in># N \<Longrightarrow> (add_mset x M) \<inter># N = add_mset x (M \<inter># (N - {#x#}))" |
770 lemma inter_add_left2: "x \<in># N \<Longrightarrow> (add_mset x M) \<inter># N = add_mset x (M \<inter># (N - {#x#}))" |
765 by (auto simp add: multiset_eq_iff elim: mset_add) |
771 by (auto simp add: multiset_eq_iff elim: mset_add) |
811 lemma inter_subset_eq_union: |
817 lemma inter_subset_eq_union: |
812 "A \<inter># B \<subseteq># A + B" |
818 "A \<inter># B \<subseteq># A + B" |
813 by (auto simp add: subseteq_mset_def) |
819 by (auto simp add: subseteq_mset_def) |
814 |
820 |
815 |
821 |
816 subsubsection \<open>Bounded union\<close> |
822 subsubsection \<open>Additional bounded union facts\<close> |
817 |
|
818 definition sup_subset_mset :: "'a multiset \<Rightarrow> 'a multiset \<Rightarrow> 'a multiset"(infixl "\<union>#" 70) |
|
819 where "sup_subset_mset A B = A + (B - A)" \<comment> \<open>FIXME irregular fact name\<close> |
|
820 |
|
821 interpretation subset_mset: semilattice_sup sup_subset_mset "op \<subseteq>#" "op \<subset>#" |
|
822 proof - |
|
823 have [simp]: "m \<le> n \<Longrightarrow> q \<le> n \<Longrightarrow> m + (q - m) \<le> n" for m n q :: nat |
|
824 by arith |
|
825 show "class.semilattice_sup op \<union># op \<subseteq># op \<subset>#" |
|
826 by standard (auto simp add: sup_subset_mset_def subseteq_mset_def) |
|
827 qed |
|
828 \<comment> \<open>FIXME: avoid junk stemming from type class interpretation\<close> |
|
829 |
|
830 interpretation subset_mset: bounded_lattice_bot "op \<inter>#" "op \<subseteq>#" "op \<subset>#" |
|
831 "op \<union>#" "{#}" |
|
832 by standard auto |
|
833 |
823 |
834 lemma sup_subset_mset_count [simp]: \<comment> \<open>FIXME irregular fact name\<close> |
824 lemma sup_subset_mset_count [simp]: \<comment> \<open>FIXME irregular fact name\<close> |
835 "count (A \<union># B) x = max (count A x) (count B x)" |
825 "count (A \<union># B) x = max (count A x) (count B x)" |
836 by (simp add: sup_subset_mset_def) |
826 by (simp add: sup_subset_mset_def) |
837 |
827 |
838 lemma set_mset_sup [simp]: |
828 lemma set_mset_sup [simp]: |
839 "set_mset (A \<union># B) = set_mset A \<union> set_mset B" |
829 "set_mset (A \<union># B) = set_mset A \<union> set_mset B" |
840 by (simp only: set_eq_iff count_greater_zero_iff [symmetric] sup_subset_mset_count) |
830 by (simp only: set_eq_iff count_greater_zero_iff [symmetric] sup_subset_mset_count) |
841 (auto simp add: not_in_iff elim: mset_add) |
831 (auto simp add: not_in_iff elim: mset_add) |
842 |
832 |
843 lemma empty_sup: "{#} \<union># M = M" |
|
844 by (fact subset_mset.sup_bot.left_neutral) |
|
845 |
|
846 lemma sup_empty: "M \<union># {#} = M" |
|
847 by (fact subset_mset.sup_bot.right_neutral) |
|
848 |
|
849 lemma sup_union_left1 [simp]: "\<not> x \<in># N \<Longrightarrow> (add_mset x M) \<union># N = add_mset x (M \<union># N)" |
833 lemma sup_union_left1 [simp]: "\<not> x \<in># N \<Longrightarrow> (add_mset x M) \<union># N = add_mset x (M \<union># N)" |
850 by (simp add: multiset_eq_iff not_in_iff) |
834 by (simp add: multiset_eq_iff not_in_iff) |
851 |
835 |
852 lemma sup_union_left2: "x \<in># N \<Longrightarrow> (add_mset x M) \<union># N = add_mset x (M \<union># (N - {#x#}))" |
836 lemma sup_union_left2: "x \<in># N \<Longrightarrow> (add_mset x M) \<union># N = add_mset x (M \<union># (N - {#x#}))" |
853 by (simp add: multiset_eq_iff) |
837 by (simp add: multiset_eq_iff) |
879 by (auto simp: multiset_eq_iff max_def) |
863 by (auto simp: multiset_eq_iff max_def) |
880 |
864 |
881 |
865 |
882 subsubsection \<open>Subset is an order\<close> |
866 subsubsection \<open>Subset is an order\<close> |
883 |
867 |
884 interpretation subset_mset: order "op \<le>#" "op <#" by unfold_locales auto |
868 interpretation subset_mset: order "op \<subseteq>#" "op \<subset>#" by unfold_locales |
885 |
869 |
886 |
870 |
887 subsection \<open>Replicate and repeat operations\<close> |
871 subsection \<open>Replicate and repeat operations\<close> |
888 |
872 |
889 definition replicate_mset :: "nat \<Rightarrow> 'a \<Rightarrow> 'a multiset" where |
873 definition replicate_mset :: "nat \<Rightarrow> 'a \<Rightarrow> 'a multiset" where |
1463 done |
1445 done |
1464 |
1446 |
1465 lemma mset_subset_size: "(A::'a multiset) \<subset># B \<Longrightarrow> size A < size B" |
1447 lemma mset_subset_size: "(A::'a multiset) \<subset># B \<Longrightarrow> size A < size B" |
1466 proof (induct A arbitrary: B) |
1448 proof (induct A arbitrary: B) |
1467 case (empty M) |
1449 case (empty M) |
1468 then have "M \<noteq> {#}" by (simp add: mset_subset_empty_nonempty) |
1450 then have "M \<noteq> {#}" by (simp add: subset_mset.zero_less_iff_neq_zero) |
1469 then obtain M' x where "M = add_mset x M'" |
1451 then obtain M' x where "M = add_mset x M'" |
1470 by (blast dest: multi_nonempty_split) |
1452 by (blast dest: multi_nonempty_split) |
1471 then show ?case by simp |
1453 then show ?case by simp |
1472 next |
1454 next |
1473 case (add x S T) |
1455 case (add x S T) |
1748 by (induct x) auto |
1730 by (induct x) auto |
1749 |
1731 |
1750 lemma mset_zero_iff_right[simp]: "({#} = mset x) = (x = [])" |
1732 lemma mset_zero_iff_right[simp]: "({#} = mset x) = (x = [])" |
1751 by (induct x) auto |
1733 by (induct x) auto |
1752 |
1734 |
1753 lemma set_mset_mset[simp]: "set_mset (mset x) = set x" |
1735 lemma set_mset_mset[simp]: "set_mset (mset xs) = set xs" |
1754 by (induct x) auto |
1736 by (induct xs) auto |
1755 |
1737 |
1756 lemma set_mset_comp_mset [simp]: "set_mset \<circ> mset = set" |
1738 lemma set_mset_comp_mset [simp]: "set_mset \<circ> mset = set" |
1757 by (simp add: fun_eq_iff) |
1739 by (simp add: fun_eq_iff) |
1758 |
1740 |
1759 lemma size_mset [simp]: "size (mset xs) = length xs" |
1741 lemma size_mset [simp]: "size (mset xs) = length xs" |
2919 |
2901 |
2920 |
2902 |
2921 subsubsection \<open>Monotonicity of multiset union\<close> |
2903 subsubsection \<open>Monotonicity of multiset union\<close> |
2922 |
2904 |
2923 lemma mult1_union: "(B, D) \<in> mult1 r \<Longrightarrow> (C + B, C + D) \<in> mult1 r" |
2905 lemma mult1_union: "(B, D) \<in> mult1 r \<Longrightarrow> (C + B, C + D) \<in> mult1 r" |
2924 apply (unfold mult1_def) |
2906 by (force simp: mult1_def) |
2925 apply auto |
|
2926 apply (rule_tac x = a in exI) |
|
2927 apply (rule_tac x = "C + M0" in exI) |
|
2928 apply (simp add: add.assoc) |
|
2929 done |
|
2930 |
2907 |
2931 lemma union_le_mono2: "B < D \<Longrightarrow> C + B < C + (D::'a::preorder multiset)" |
2908 lemma union_le_mono2: "B < D \<Longrightarrow> C + B < C + (D::'a::preorder multiset)" |
2932 apply (unfold less_multiset_def mult_def) |
2909 apply (unfold less_multiset_def mult_def) |
2933 apply (erule trancl_induct) |
2910 apply (erule trancl_induct) |
2934 apply (blast intro: mult1_union) |
2911 apply (blast intro: mult1_union) |
3264 lemma subset_eq_mset_impl: "(subset_eq_mset_impl xs ys = None \<longleftrightarrow> \<not> mset xs \<subseteq># mset ys) \<and> |
3241 lemma subset_eq_mset_impl: "(subset_eq_mset_impl xs ys = None \<longleftrightarrow> \<not> mset xs \<subseteq># mset ys) \<and> |
3265 (subset_eq_mset_impl xs ys = Some True \<longleftrightarrow> mset xs \<subset># mset ys) \<and> |
3242 (subset_eq_mset_impl xs ys = Some True \<longleftrightarrow> mset xs \<subset># mset ys) \<and> |
3266 (subset_eq_mset_impl xs ys = Some False \<longrightarrow> mset xs = mset ys)" |
3243 (subset_eq_mset_impl xs ys = Some False \<longrightarrow> mset xs = mset ys)" |
3267 proof (induct xs arbitrary: ys) |
3244 proof (induct xs arbitrary: ys) |
3268 case (Nil ys) |
3245 case (Nil ys) |
3269 show ?case by (auto simp: mset_subset_empty_nonempty) |
3246 show ?case by (auto simp: subset_mset.zero_less_iff_neq_zero) |
3270 next |
3247 next |
3271 case (Cons x xs ys) |
3248 case (Cons x xs ys) |
3272 show ?case |
3249 show ?case |
3273 proof (cases "List.extract (op = x) ys") |
3250 proof (cases "List.extract (op = x) ys") |
3274 case None |
3251 case None |