src/HOL/Library/Disjoint_Sets.thy
changeset 63098 56f03591898b
parent 62843 313d3b697c9a
child 63100 aa5cffd8a606
equal deleted inserted replaced
63097:ee8edbcbb4ad 63098:56f03591898b
     1 (*  Title:      HOL/Library/Disjoint_Sets.thy
     1 (*  Title:      HOL/Library/Disjoint_Sets.thy
     2     Author:     Johannes Hölzl, TU München
     2     Author:     Johannes Hölzl, TU München
     3 *)
     3 *)
     4 
     4 
     5 section \<open>Handling Disjoint Sets\<close>
     5 section \<open>Partitions and Disjoint Sets\<close>
     6 
     6 
     7 theory Disjoint_Sets
     7 theory Disjoint_Sets
     8   imports Main
     8   imports Main
     9 begin
     9 begin
    10 
    10 
    17 lemma Int_Diff_Un: "A \<inter> B \<union> (A - B) = A"
    17 lemma Int_Diff_Un: "A \<inter> B \<union> (A - B) = A"
    18   by blast
    18   by blast
    19 
    19 
    20 lemma mono_Un: "mono A \<Longrightarrow> (\<Union>i\<le>n. A i) = A n"
    20 lemma mono_Un: "mono A \<Longrightarrow> (\<Union>i\<le>n. A i) = A n"
    21   unfolding mono_def by auto
    21   unfolding mono_def by auto
       
    22 
       
    23 lemma disjnt_equiv_class: "equiv A r \<Longrightarrow> disjnt (r``{a}) (r``{b}) \<longleftrightarrow> (a, b) \<notin> r"
       
    24   by (auto dest: equiv_class_self simp: equiv_class_eq_iff disjnt_def)
    22 
    25 
    23 subsection \<open>Set of Disjoint Sets\<close>
    26 subsection \<open>Set of Disjoint Sets\<close>
    24 
    27 
    25 abbreviation disjoint :: "'a set set \<Rightarrow> bool" where "disjoint \<equiv> pairwise disjnt"
    28 abbreviation disjoint :: "'a set set \<Rightarrow> bool" where "disjoint \<equiv> pairwise disjnt"
    26 
    29 
    37 
    40 
    38 lemma disjoint_INT:
    41 lemma disjoint_INT:
    39   assumes *: "\<And>i. i \<in> I \<Longrightarrow> disjoint (F i)"
    42   assumes *: "\<And>i. i \<in> I \<Longrightarrow> disjoint (F i)"
    40   shows "disjoint {\<Inter>i\<in>I. X i | X. \<forall>i\<in>I. X i \<in> F i}"
    43   shows "disjoint {\<Inter>i\<in>I. X i | X. \<forall>i\<in>I. X i \<in> F i}"
    41 proof (safe intro!: disjointI del: equalityI)
    44 proof (safe intro!: disjointI del: equalityI)
    42   fix A B :: "'a \<Rightarrow> 'b set" assume "(\<Inter>i\<in>I. A i) \<noteq> (\<Inter>i\<in>I. B i)" 
    45   fix A B :: "'a \<Rightarrow> 'b set" assume "(\<Inter>i\<in>I. A i) \<noteq> (\<Inter>i\<in>I. B i)"
    43   then obtain i where "A i \<noteq> B i" "i \<in> I"
    46   then obtain i where "A i \<noteq> B i" "i \<in> I"
    44     by auto
    47     by auto
    45   moreover assume "\<forall>i\<in>I. A i \<in> F i" "\<forall>i\<in>I. B i \<in> F i"
    48   moreover assume "\<forall>i\<in>I. A i \<in> F i" "\<forall>i\<in>I. B i \<in> F i"
    46   ultimately show "(\<Inter>i\<in>I. A i) \<inter> (\<Inter>i\<in>I. B i) = {}"
    49   ultimately show "(\<Inter>i\<in>I. A i) \<inter> (\<Inter>i\<in>I. B i) = {}"
    47     using *[OF \<open>i\<in>I\<close>, THEN disjointD, of "A i" "B i"]
    50     using *[OF \<open>i\<in>I\<close>, THEN disjointD, of "A i" "B i"]
   148   by (simp add: disjointed_def)
   151   by (simp add: disjointed_def)
   149 
   152 
   150 lemma disjointed_mono: "mono A \<Longrightarrow> disjointed A (Suc n) = A (Suc n) - A n"
   153 lemma disjointed_mono: "mono A \<Longrightarrow> disjointed A (Suc n) = A (Suc n) - A n"
   151   using mono_Un[of A] by (simp add: disjointed_def atLeastLessThanSuc_atLeastAtMost atLeast0AtMost)
   154   using mono_Un[of A] by (simp add: disjointed_def atLeastLessThanSuc_atLeastAtMost atLeast0AtMost)
   152 
   155 
       
   156 subsection \<open>Partitions\<close>
       
   157 
       
   158 text \<open>
       
   159   Partitions @{term P} of a set @{term A}. We explicitly disallow empty sets.
       
   160 \<close>
       
   161 
       
   162 definition partition_on :: "'a set \<Rightarrow> 'a set set \<Rightarrow> bool"
       
   163 where
       
   164   "partition_on A P \<longleftrightarrow> \<Union>P = A \<and> disjoint P \<and> {} \<notin> P"
       
   165 
       
   166 lemma partition_onI:
       
   167   "\<Union>P = A \<Longrightarrow> (\<And>p q. p \<in> P \<Longrightarrow> q \<in> P \<Longrightarrow> p \<noteq> q \<Longrightarrow> disjnt p q) \<Longrightarrow> {} \<notin> P \<Longrightarrow> partition_on A P"
       
   168   by (auto simp: partition_on_def pairwise_def)
       
   169 
       
   170 lemma partition_onD1: "partition_on A P \<Longrightarrow> A = \<Union>P"
       
   171   by (auto simp: partition_on_def)
       
   172 
       
   173 lemma partition_onD2: "partition_on A P \<Longrightarrow> disjoint P"
       
   174   by (auto simp: partition_on_def)
       
   175 
       
   176 lemma partition_onD3: "partition_on A P \<Longrightarrow> {} \<notin> P"
       
   177   by (auto simp: partition_on_def)
       
   178 
       
   179 subsection \<open>Constructions of partitions\<close>
       
   180 
       
   181 lemma partition_on_empty: "partition_on {} P \<longleftrightarrow> P = {}"
       
   182   unfolding partition_on_def by fastforce
       
   183 
       
   184 lemma partition_on_space: "A \<noteq> {} \<Longrightarrow> partition_on A {A}"
       
   185   by (auto simp: partition_on_def disjoint_def)
       
   186 
       
   187 lemma partition_on_singletons: "partition_on A ((\<lambda>x. {x}) ` A)"
       
   188   by (auto simp: partition_on_def disjoint_def)
       
   189 
       
   190 lemma partition_on_transform:
       
   191   assumes P: "partition_on A P"
       
   192   assumes F_UN: "\<Union>(F ` P) = F (\<Union>P)" and F_disjnt: "\<And>p q. p \<in> P \<Longrightarrow> q \<in> P \<Longrightarrow> disjnt p q \<Longrightarrow> disjnt (F p) (F q)"
       
   193   shows "partition_on (F A) (F ` P - {{}})"
       
   194 proof -
       
   195   have "\<Union>(F ` P - {{}}) = F A"
       
   196     unfolding P[THEN partition_onD1] F_UN[symmetric] by auto
       
   197   with P show ?thesis
       
   198     by (auto simp add: partition_on_def pairwise_def intro!: F_disjnt)
       
   199 qed
       
   200 
       
   201 lemma partition_on_restrict: "partition_on A P \<Longrightarrow> partition_on (B \<inter> A) (op \<inter> B ` P - {{}})"
       
   202   by (intro partition_on_transform) (auto simp: disjnt_def)
       
   203 
       
   204 lemma partition_on_vimage: "partition_on A P \<Longrightarrow> partition_on (f -` A) (op -` f ` P - {{}})"
       
   205   by (intro partition_on_transform) (auto simp: disjnt_def)
       
   206 
       
   207 lemma partition_on_inj_image:
       
   208   assumes P: "partition_on A P" and f: "inj_on f A"
       
   209   shows "partition_on (f ` A) (op ` f ` P - {{}})"
       
   210 proof (rule partition_on_transform[OF P])
       
   211   show "p \<in> P \<Longrightarrow> q \<in> P \<Longrightarrow> disjnt p q \<Longrightarrow> disjnt (f ` p) (f ` q)" for p q
       
   212     using f[THEN inj_onD] P[THEN partition_onD1] by (auto simp: disjnt_def)
       
   213 qed auto
       
   214 
       
   215 subsection \<open>Finiteness of partitions\<close>
       
   216 
       
   217 lemma finitely_many_partition_on:
       
   218   assumes "finite A"
       
   219   shows "finite {P. partition_on A P}"
       
   220 proof (rule finite_subset)
       
   221   show "{P. partition_on A P} \<subseteq> Pow (Pow A)"
       
   222     unfolding partition_on_def by auto
       
   223   show "finite (Pow (Pow A))"
       
   224     using assms by simp
       
   225 qed
       
   226 
       
   227 lemma finite_elements: "finite A \<Longrightarrow> partition_on A P \<Longrightarrow> finite P"
       
   228   using partition_onD1[of A P] by (simp add: finite_UnionD)
       
   229 
       
   230 subsection \<open>Equivalence of partitions and equivalence classes\<close>
       
   231 
       
   232 lemma partition_on_quotient:
       
   233   assumes r: "equiv A r"
       
   234   shows "partition_on A (A // r)"
       
   235 proof (rule partition_onI)
       
   236   from r have "refl_on A r"
       
   237     by (auto elim: equivE)
       
   238   then show "\<Union>(A // r) = A" "{} \<notin> A // r"
       
   239     by (auto simp: refl_on_def quotient_def)
       
   240 
       
   241   fix p q assume "p \<in> A // r" "q \<in> A // r" "p \<noteq> q"
       
   242   then obtain x y where "x \<in> A" "y \<in> A" "p = r `` {x}" "q = r `` {y}"
       
   243     by (auto simp: quotient_def)
       
   244   with r equiv_class_eq_iff[OF r, of x y] \<open>p \<noteq> q\<close> show "disjnt p q"
       
   245     by (auto simp: disjnt_equiv_class)
       
   246 qed
       
   247 
       
   248 lemma equiv_partition_on:
       
   249   assumes P: "partition_on A P"
       
   250   shows "equiv A {(x, y). \<exists>p \<in> P. x \<in> p \<and> y \<in> p}"
       
   251 proof (rule equivI)
       
   252   have "A = \<Union>P" "disjoint P" "{} \<notin> P"
       
   253     using P by (auto simp: partition_on_def)
       
   254   then show "refl_on A {(x, y). \<exists>p\<in>P. x \<in> p \<and> y \<in> p}"
       
   255     unfolding refl_on_def by auto
       
   256   show "trans {(x, y). \<exists>p\<in>P. x \<in> p \<and> y \<in> p}"
       
   257     using \<open>disjoint P\<close> by (auto simp: trans_def disjoint_def)
       
   258 qed (auto simp: sym_def)
       
   259 
       
   260 lemma partition_on_eq_quotient:
       
   261   assumes P: "partition_on A P"
       
   262   shows "A // {(x, y). \<exists>p \<in> P. x \<in> p \<and> y \<in> p} = P"
       
   263   unfolding quotient_def
       
   264 proof safe
       
   265   fix x assume "x \<in> A"
       
   266   then obtain p where "p \<in> P" "x \<in> p" "\<And>q. q \<in> P \<Longrightarrow> x \<in> q \<Longrightarrow> p = q"
       
   267     using P by (auto simp: partition_on_def disjoint_def)
       
   268   then have "{y. \<exists>p\<in>P. x \<in> p \<and> y \<in> p} = p"
       
   269     by (safe intro!: bexI[of _ p]) simp
       
   270   then show "{(x, y). \<exists>p\<in>P. x \<in> p \<and> y \<in> p} `` {x} \<in> P"
       
   271     by (simp add: \<open>p \<in> P\<close>)
       
   272 next
       
   273   fix p assume "p \<in> P"
       
   274   then have "p \<noteq> {}"
       
   275     using P by (auto simp: partition_on_def)
       
   276   then obtain x where "x \<in> p"
       
   277     by auto
       
   278   then have "x \<in> A" "\<And>q. q \<in> P \<Longrightarrow> x \<in> q \<Longrightarrow> p = q"
       
   279     using P \<open>p \<in> P\<close> by (auto simp: partition_on_def disjoint_def)
       
   280   with \<open>p\<in>P\<close> \<open>x \<in> p\<close> have "{y. \<exists>p\<in>P. x \<in> p \<and> y \<in> p} = p"
       
   281     by (safe intro!: bexI[of _ p]) simp
       
   282   then show "p \<in> (\<Union>x\<in>A. {{(x, y). \<exists>p\<in>P. x \<in> p \<and> y \<in> p} `` {x}})"
       
   283     by (auto intro: \<open>x \<in> A\<close>)
       
   284 qed
       
   285 
       
   286 lemma partition_on_alt: "partition_on A P \<longleftrightarrow> (\<exists>r. equiv A r \<and> P = A // r)"
       
   287   by (auto simp: partition_on_eq_quotient intro!: partition_on_quotient intro: equiv_partition_on)
       
   288 
   153 end
   289 end