src/HOL/Library/Confluent_Quotient.thy
changeset 73398 180981b87929
parent 71393 fce780f9c9c6
equal deleted inserted replaced
73397:d47c8a89c6a5 73398:180981b87929
     1 theory Confluent_Quotient imports 
     1 theory Confluent_Quotient imports
     2   Confluence
     2   Confluence
     3 begin
     3 begin
     4 
     4 
     5 section \<open>Subdistributivity for quotients via confluence\<close>
     5 text \<open>Functors with finite setters preserve wide intersection for any equivalence relation that respects the mapper.\<close>
       
     6 
       
     7 lemma Inter_finite_subset:
       
     8   assumes "\<forall>A \<in> \<A>. finite A"
       
     9   shows "\<exists>\<B>\<subseteq>\<A>. finite \<B> \<and> (\<Inter>\<B>) = (\<Inter>\<A>)"
       
    10 proof(cases "\<A> = {}")
       
    11   case False
       
    12   then obtain A where A: "A \<in> \<A>" by auto
       
    13   then have finA: "finite A" using assms by auto
       
    14   hence fin: "finite (A - \<Inter>\<A>)" by(rule finite_subset[rotated]) auto
       
    15   let ?P = "\<lambda>x A. A \<in> \<A> \<and> x \<notin> A"
       
    16   define f where "f x = Eps (?P x)" for x
       
    17   let ?\<B> = "insert A (f ` (A - \<Inter>\<A>))"
       
    18   have "?P x (f x)" if "x \<in> A - \<Inter>\<A>" for x unfolding f_def by(rule someI_ex)(use that A in auto)
       
    19   hence "(\<Inter>?\<B>) = (\<Inter>\<A>)" "?\<B> \<subseteq> \<A>" using A by auto
       
    20   moreover have "finite ?\<B>" using fin by simp
       
    21   ultimately show ?thesis by blast
       
    22 qed simp
       
    23 
       
    24 locale wide_intersection_finite =
       
    25   fixes E :: "'Fa \<Rightarrow> 'Fa \<Rightarrow> bool"
       
    26     and mapFa :: "('a \<Rightarrow> 'a) \<Rightarrow> 'Fa \<Rightarrow> 'Fa"
       
    27     and setFa :: "'Fa \<Rightarrow> 'a set"
       
    28   assumes equiv: "equivp E"
       
    29     and map_E: "E x y \<Longrightarrow> E (mapFa f x) (mapFa f y)"
       
    30     and map_id: "mapFa id x = x"
       
    31     and map_cong: "\<forall>a\<in>setFa x. f a = g a \<Longrightarrow> mapFa f x = mapFa g x"
       
    32     and set_map: "setFa (mapFa f x) = f ` setFa x"
       
    33     and finite: "finite (setFa x)"
       
    34 begin
       
    35 
       
    36 lemma binary_intersection:
       
    37   assumes "E y z" and y: "setFa y \<subseteq> Y" and z: "setFa z \<subseteq> Z" and a: "a \<in> Y" "a \<in> Z"
       
    38   shows "\<exists>x. E x y \<and> setFa x \<subseteq> Y \<and> setFa x \<subseteq> Z"
       
    39 proof -
       
    40   let ?f = "\<lambda>b. if b \<in> Z then b else a"
       
    41   let ?u = "mapFa ?f y"
       
    42   from \<open>E y z\<close> have "E ?u (mapFa ?f z)" by(rule map_E)
       
    43   also have "mapFa ?f z = mapFa id z" by(rule map_cong)(use z in auto)
       
    44   also have "\<dots> = z" by(rule map_id)
       
    45   finally have "E ?u y" using \<open>E y z\<close> equivp_symp[OF equiv] equivp_transp[OF equiv] by blast
       
    46   moreover have "setFa ?u \<subseteq> Y" using a y by(subst set_map) auto
       
    47   moreover have "setFa ?u \<subseteq> Z" using a by(subst set_map) auto
       
    48   ultimately show ?thesis by blast
       
    49 qed
       
    50 
       
    51 lemma finite_intersection:
       
    52   assumes E: "\<forall>y\<in>A. E y z"
       
    53     and fin: "finite A"
       
    54     and sub: "\<forall>y\<in>A. setFa y \<subseteq> Y y \<and> a \<in> Y y"
       
    55   shows "\<exists>x. E x z \<and> (\<forall>y\<in>A. setFa x \<subseteq> Y y)"
       
    56   using fin E sub
       
    57 proof(induction)
       
    58   case empty
       
    59   then show ?case using equivp_reflp[OF equiv, of z] by(auto)
       
    60 next
       
    61   case (insert y A)
       
    62   then obtain x where x: "E x z" "\<forall>y\<in>A. setFa x \<subseteq> Y y \<and> a \<in> Y y" by auto
       
    63   hence set_x: "setFa x \<subseteq> (\<Inter>y\<in>A. Y y)" "a \<in> (\<Inter>y\<in>A. Y y)" by auto
       
    64   from insert.prems have "E y z" and set_y: "setFa y \<subseteq> Y y" "a \<in> Y y" by auto
       
    65   from \<open>E y z\<close> \<open>E x z\<close> have "E x y" using equivp_symp[OF equiv] equivp_transp[OF equiv] by blast
       
    66   from binary_intersection[OF this set_x(1) set_y(1) set_x(2) set_y(2)]
       
    67   obtain x' where "E x' x" "setFa x' \<subseteq> \<Inter> (Y ` A)" "setFa x' \<subseteq> Y y" by blast
       
    68   then show ?case using \<open>E x z\<close> equivp_transp[OF equiv] by blast
       
    69 qed
       
    70 
       
    71 lemma wide_intersection:
       
    72   assumes inter_nonempty: "\<Inter> Ss \<noteq> {}"
       
    73   shows "(\<Inter>As \<in> Ss. {(x, x'). E x x'} `` {x. setFa x \<subseteq> As}) \<subseteq> {(x, x'). E x x'} `` {x. setFa x \<subseteq> \<Inter> Ss}" (is "?lhs \<subseteq> ?rhs")
       
    74 proof
       
    75   fix x
       
    76   assume lhs: "x \<in> ?lhs"
       
    77   from inter_nonempty obtain a where a: "\<forall>As \<in> Ss. a \<in> As" by auto
       
    78   from lhs obtain y where y: "\<And>As. As \<in> Ss \<Longrightarrow> E (y As) x \<and> setFa (y As) \<subseteq> As"
       
    79     by atomize_elim(rule choice, auto)
       
    80   define Ts where "Ts = (\<lambda>As. insert a (setFa (y As))) ` Ss"
       
    81   have Ts_subset: "(\<Inter>Ts) \<subseteq> (\<Inter>Ss)" using a unfolding Ts_def by(auto dest: y)
       
    82   have Ts_finite: "\<forall>Bs \<in> Ts. finite Bs" unfolding Ts_def by(auto dest: y intro: finite)
       
    83   from Inter_finite_subset[OF this] obtain Us
       
    84     where Us: "Us \<subseteq> Ts" and finite_Us: "finite Us" and Int_Us: "(\<Inter>Us) \<subseteq> (\<Inter>Ts)" by force
       
    85   let ?P = "\<lambda>U As. As \<in> Ss \<and> U = insert a (setFa (y As))"
       
    86   define Y where "Y U = Eps (?P U)" for U
       
    87   have Y: "?P U (Y U)" if "U \<in> Us" for U unfolding Y_def
       
    88     by(rule someI_ex)(use that Us in \<open>auto simp add: Ts_def\<close>)
       
    89   let ?f = "\<lambda>U. y (Y U)"
       
    90   have *: "\<forall>z\<in>(?f ` Us). E z x" by(auto dest!: Y y)
       
    91   have **: "\<forall>z\<in>(?f ` Us). setFa z \<subseteq> insert a (setFa z) \<and> a \<in> insert a (setFa z)" by auto
       
    92   from finite_intersection[OF * _ **] finite_Us obtain u
       
    93     where u: "E u x" and set_u: "\<forall>z\<in>(?f ` Us). setFa u \<subseteq> insert a (setFa z)" by auto
       
    94   from set_u have "setFa u \<subseteq> (\<Inter> Us)" by(auto dest: Y)
       
    95   with Int_Us Ts_subset have "setFa u \<subseteq> (\<Inter> Ss)" by auto
       
    96   with u show "x \<in> ?rhs" by auto
       
    97 qed
       
    98 
       
    99 end
       
   100 
       
   101 text \<open>Subdistributivity for quotients via confluence\<close>
       
   102 
       
   103 lemma rtranclp_transp_reflp: "R\<^sup>*\<^sup>* = R" if "transp R" "reflp R"
       
   104   apply(rule ext iffI)+
       
   105   subgoal premises prems for x y using prems by(induction)(use that in \<open>auto intro: reflpD transpD\<close>)
       
   106   subgoal by(rule r_into_rtranclp)
       
   107   done
       
   108 
       
   109 lemma rtranclp_equivp: "R\<^sup>*\<^sup>* = R" if "equivp R"
       
   110   using that by(simp add: rtranclp_transp_reflp equivp_reflp_symp_transp)
     6 
   111 
     7 locale confluent_quotient =
   112 locale confluent_quotient =
     8   fixes R :: "'Fb \<Rightarrow> 'Fb \<Rightarrow> bool"
   113   fixes Rb :: "'Fb \<Rightarrow> 'Fb \<Rightarrow> bool"
     9     and Ea :: "'Fa \<Rightarrow> 'Fa \<Rightarrow> bool"
   114     and Ea :: "'Fa \<Rightarrow> 'Fa \<Rightarrow> bool"
    10     and Eb :: "'Fb \<Rightarrow> 'Fb \<Rightarrow> bool"
   115     and Eb :: "'Fb \<Rightarrow> 'Fb \<Rightarrow> bool"
    11     and Ec :: "'Fc \<Rightarrow> 'Fc \<Rightarrow> bool"
   116     and Ec :: "'Fc \<Rightarrow> 'Fc \<Rightarrow> bool"
    12     and Eab :: "'Fab \<Rightarrow> 'Fab \<Rightarrow> bool"
   117     and Eab :: "'Fab \<Rightarrow> 'Fab \<Rightarrow> bool"
    13     and Ebc :: "'Fbc \<Rightarrow> 'Fbc \<Rightarrow> bool"
   118     and Ebc :: "'Fbc \<Rightarrow> 'Fbc \<Rightarrow> bool"
    18     and rel_Fab :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> 'Fa \<Rightarrow> 'Fb \<Rightarrow> bool"
   123     and rel_Fab :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> 'Fa \<Rightarrow> 'Fb \<Rightarrow> bool"
    19     and rel_Fbc :: "('b \<Rightarrow> 'c \<Rightarrow> bool) \<Rightarrow> 'Fb \<Rightarrow> 'Fc \<Rightarrow> bool"
   124     and rel_Fbc :: "('b \<Rightarrow> 'c \<Rightarrow> bool) \<Rightarrow> 'Fb \<Rightarrow> 'Fc \<Rightarrow> bool"
    20     and rel_Fac :: "('a \<Rightarrow> 'c \<Rightarrow> bool) \<Rightarrow> 'Fa \<Rightarrow> 'Fc \<Rightarrow> bool"
   125     and rel_Fac :: "('a \<Rightarrow> 'c \<Rightarrow> bool) \<Rightarrow> 'Fa \<Rightarrow> 'Fc \<Rightarrow> bool"
    21     and set_Fab :: "'Fab \<Rightarrow> ('a \<times> 'b) set"
   126     and set_Fab :: "'Fab \<Rightarrow> ('a \<times> 'b) set"
    22     and set_Fbc :: "'Fbc \<Rightarrow> ('b \<times> 'c) set"
   127     and set_Fbc :: "'Fbc \<Rightarrow> ('b \<times> 'c) set"
    23   assumes confluent: "confluentp R"
   128   assumes confluent: "confluentp Rb"
    24     and retract1_ab: "\<And>x y. R (\<pi>_Fabb x) y \<Longrightarrow> \<exists>z. Eab x z \<and> y = \<pi>_Fabb z"
   129     and retract1_ab: "\<And>x y. Rb (\<pi>_Fabb x) y \<Longrightarrow> \<exists>z. Eab x z \<and> y = \<pi>_Fabb z \<and> set_Fab z \<subseteq> set_Fab x"
    25     and retract1_bc: "\<And>x y. R (\<pi>_Fbcb x) y \<Longrightarrow> \<exists>z. Ebc x z \<and> y = \<pi>_Fbcb z"
   130     and retract1_bc: "\<And>x y. Rb (\<pi>_Fbcb x) y \<Longrightarrow> \<exists>z. Ebc x z \<and> y = \<pi>_Fbcb z \<and> set_Fbc z \<subseteq> set_Fbc x"
    26     and generated: "Eb \<le> equivclp R"
   131     and generated_b: "Eb \<le> equivclp Rb"
    27     and set_ab: "\<And>x y. Eab x y \<Longrightarrow> set_Fab x = set_Fab y"
       
    28     and set_bc: "\<And>x y. Ebc x y \<Longrightarrow> set_Fbc x = set_Fbc y"
       
    29     and transp_a: "transp Ea"
   132     and transp_a: "transp Ea"
    30     and transp_c: "transp Ec"
   133     and transp_c: "transp Ec"
    31     and equivp_ab: "equivp Eab"
   134     and equivp_ab: "equivp Eab"
    32     and equivp_bc: "equivp Ebc"
   135     and equivp_bc: "equivp Ebc"
    33     and in_rel_Fab: "\<And>A x y. rel_Fab A x y \<longleftrightarrow> (\<exists>z. z \<in> {x. set_Fab x \<subseteq> {(x, y). A x y}} \<and> \<pi>_Faba z = x \<and> \<pi>_Fabb z = y)"
   136     and in_rel_Fab: "\<And>A x y. rel_Fab A x y \<longleftrightarrow> (\<exists>z. z \<in> {x. set_Fab x \<subseteq> {(x, y). A x y}} \<and> \<pi>_Faba z = x \<and> \<pi>_Fabb z = y)"
    35     and rel_compp: "\<And>A B. rel_Fac (A OO B) = rel_Fab A OO rel_Fbc B"
   138     and rel_compp: "\<And>A B. rel_Fac (A OO B) = rel_Fab A OO rel_Fbc B"
    36     and \<pi>_Faba_respect: "rel_fun Eab Ea \<pi>_Faba \<pi>_Faba"
   139     and \<pi>_Faba_respect: "rel_fun Eab Ea \<pi>_Faba \<pi>_Faba"
    37     and \<pi>_Fbcc_respect: "rel_fun Ebc Ec \<pi>_Fbcc \<pi>_Fbcc"
   140     and \<pi>_Fbcc_respect: "rel_fun Ebc Ec \<pi>_Fbcc \<pi>_Fbcc"
    38 begin
   141 begin
    39 
   142 
    40 lemma retract_ab: "R\<^sup>*\<^sup>* (\<pi>_Fabb x) y \<Longrightarrow> \<exists>z. Eab x z \<and> y = \<pi>_Fabb z"
   143 lemma retract_ab: "Rb\<^sup>*\<^sup>* (\<pi>_Fabb x) y \<Longrightarrow> \<exists>z. Eab x z \<and> y = \<pi>_Fabb z \<and> set_Fab z \<subseteq> set_Fab x"
    41   by(induction rule: rtranclp_induct)(blast dest: retract1_ab intro: equivp_transp[OF equivp_ab] equivp_reflp[OF equivp_ab])+
   144   by(induction rule: rtranclp_induct)(blast dest: retract1_ab intro: equivp_transp[OF equivp_ab] equivp_reflp[OF equivp_ab])+
    42 
   145 
    43 lemma retract_bc: "R\<^sup>*\<^sup>* (\<pi>_Fbcb x) y \<Longrightarrow> \<exists>z. Ebc x z \<and> y = \<pi>_Fbcb z"
   146 lemma retract_bc: "Rb\<^sup>*\<^sup>* (\<pi>_Fbcb x) y \<Longrightarrow> \<exists>z. Ebc x z \<and> y = \<pi>_Fbcb z \<and> set_Fbc z \<subseteq> set_Fbc x"
    44   by(induction rule: rtranclp_induct)(blast dest: retract1_bc intro: equivp_transp[OF equivp_bc] equivp_reflp[OF equivp_bc])+
   147   by(induction rule: rtranclp_induct)(blast dest: retract1_bc intro: equivp_transp[OF equivp_bc] equivp_reflp[OF equivp_bc])+
    45 
   148 
    46 lemma subdistributivity: "rel_Fab A OO Eb OO rel_Fbc B \<le> Ea OO rel_Fac (A OO B) OO Ec"
   149 lemma subdistributivity: "rel_Fab A OO Eb OO rel_Fbc B \<le> Ea OO rel_Fac (A OO B) OO Ec"
    47 proof(rule predicate2I; elim relcomppE)
   150 proof(rule predicate2I; elim relcomppE)
    48   fix x y y' z
   151   fix x y y' z
    49   assume "rel_Fab A x y" and "Eb y y'" and "rel_Fbc B y' z"
   152   assume "rel_Fab A x y" and "Eb y y'" and "rel_Fbc B y' z"
    50   then obtain xy y'z
   153   then obtain xy y'z
    51     where xy: "set_Fab xy \<subseteq> {(a, b). A a b}" "x = \<pi>_Faba xy" "y = \<pi>_Fabb xy"
   154     where xy: "set_Fab xy \<subseteq> {(a, b). A a b}" "x = \<pi>_Faba xy" "y = \<pi>_Fabb xy"
    52       and y'z: "set_Fbc y'z \<subseteq> {(a, b). B a b}" "y' = \<pi>_Fbcb y'z" "z = \<pi>_Fbcc y'z"
   155       and y'z: "set_Fbc y'z \<subseteq> {(a, b). B a b}" "y' = \<pi>_Fbcb y'z" "z = \<pi>_Fbcc y'z"
    53     by(auto simp add: in_rel_Fab in_rel_Fbc)
   156     by(auto simp add: in_rel_Fab in_rel_Fbc)
    54   from \<open>Eb y y'\<close> have "equivclp R y y'" using generated by blast
   157   from \<open>Eb y y'\<close> have "equivclp Rb y y'" using generated_b by blast
    55   then obtain u where u: "R\<^sup>*\<^sup>* y u" "R\<^sup>*\<^sup>* y' u"
   158   then obtain u where u: "Rb\<^sup>*\<^sup>* y u" "Rb\<^sup>*\<^sup>* y' u"
    56     unfolding semiconfluentp_equivclp[OF confluent[THEN confluentp_imp_semiconfluentp]]
   159     unfolding semiconfluentp_equivclp[OF confluent[THEN confluentp_imp_semiconfluentp]]
    57     by(auto simp add: rtranclp_conversep)
   160     by(auto simp add: rtranclp_conversep)
    58   with xy y'z obtain xy' y'z'
   161   with xy y'z obtain xy' y'z'
    59     where retract1: "Eab xy xy'" "\<pi>_Fabb xy' = u"
   162     where retract1: "Eab xy xy'" "\<pi>_Fabb xy' = u" "set_Fab xy' \<subseteq> set_Fab xy"
    60       and retract2: "Ebc y'z y'z'" "\<pi>_Fbcb y'z' = u"
   163       and retract2: "Ebc y'z y'z'" "\<pi>_Fbcb y'z' = u" "set_Fbc y'z' \<subseteq> set_Fbc y'z"
    61     by(auto dest!: retract_ab retract_bc)
   164     by(auto dest!: retract_ab retract_bc)
    62   from retract1(1) xy have "Ea x (\<pi>_Faba xy')" by(auto dest: \<pi>_Faba_respect[THEN rel_funD])
   165   from retract1(1) xy have "Ea x (\<pi>_Faba xy')" by(auto dest: \<pi>_Faba_respect[THEN rel_funD])
    63   moreover have "rel_Fab A (\<pi>_Faba xy') u" using xy retract1
   166   moreover have "rel_Fab A (\<pi>_Faba xy') u" using xy retract1 by(auto simp add: in_rel_Fab)
    64     by(auto simp add: in_rel_Fab dest: set_ab)
   167   moreover have "rel_Fbc B u (\<pi>_Fbcc y'z')" using y'z retract2 by(auto simp add: in_rel_Fbc)
    65   moreover have "rel_Fbc B u (\<pi>_Fbcc y'z')" using y'z retract2
       
    66     by(auto simp add: in_rel_Fbc dest: set_bc)
       
    67   moreover have "Ec (\<pi>_Fbcc y'z') z" using retract2 y'z equivp_symp[OF equivp_bc]
   168   moreover have "Ec (\<pi>_Fbcc y'z') z" using retract2 y'z equivp_symp[OF equivp_bc]
    68     by(auto dest: \<pi>_Fbcc_respect[THEN rel_funD])
   169     by(auto intro: \<pi>_Fbcc_respect[THEN rel_funD])
    69   ultimately show "(Ea OO rel_Fac (A OO B) OO Ec) x z" unfolding rel_compp by blast
   170   ultimately show "(Ea OO rel_Fac (A OO B) OO Ec) x z" unfolding rel_compp by blast
    70 qed
   171 qed
    71 
   172 
    72 end
   173 end
    73 
   174