src/HOL/Transitive_Closure.thy
changeset 71393 fce780f9c9c6
parent 70749 5d06b7bb9d22
child 71627 2a24c2015a61
equal deleted inserted replaced
71392:a3f7f00b4fd8 71393:fce780f9c9c6
   536   proof (cases a b rule: rtranclE)
   536   proof (cases a b rule: rtranclE)
   537     case step
   537     case step
   538     show ?thesis
   538     show ?thesis
   539       by (rule rtrancl_into_trancl1) (use step in auto)
   539       by (rule rtrancl_into_trancl1) (use step in auto)
   540   qed auto
   540   qed auto
   541   ultimately show ?thesis 
   541   ultimately show ?thesis
   542     by auto
   542     by auto
   543 qed
   543 qed
   544 
   544 
   545 lemma rtrancl_trancl_reflcl [code]: "r\<^sup>* = (r\<^sup>+)\<^sup>="
   545 lemma rtrancl_trancl_reflcl [code]: "r\<^sup>* = (r\<^sup>+)\<^sup>="
   546   by simp
   546   by simp
   617   by (unfold Domain_unfold) (blast dest: tranclD)
   617   by (unfold Domain_unfold) (blast dest: tranclD)
   618 
   618 
   619 lemma trancl_range [simp]: "Range (r\<^sup>+) = Range r"
   619 lemma trancl_range [simp]: "Range (r\<^sup>+) = Range r"
   620   unfolding Domain_converse [symmetric] by (simp add: trancl_converse [symmetric])
   620   unfolding Domain_converse [symmetric] by (simp add: trancl_converse [symmetric])
   621 
   621 
   622 lemma Not_Domain_rtrancl: 
   622 lemma Not_Domain_rtrancl:
   623   assumes "x \<notin> Domain R" shows "(x, y) \<in> R\<^sup>* \<longleftrightarrow> x = y"
   623   assumes "x \<notin> Domain R" shows "(x, y) \<in> R\<^sup>* \<longleftrightarrow> x = y"
   624 proof -
   624 proof -
   625 have "(x, y) \<in> R\<^sup>* \<Longrightarrow> x = y"
   625 have "(x, y) \<in> R\<^sup>* \<Longrightarrow> x = y"
   626   by (erule rtrancl_induct) (use assms in auto)
   626   by (erule rtrancl_induct) (use assms in auto)
   627   then show ?thesis
   627   then show ?thesis
   659   shows "(y, z) \<in> r\<^sup>* \<or> (z, y) \<in> r\<^sup>*"
   659   shows "(y, z) \<in> r\<^sup>* \<or> (z, y) \<in> r\<^sup>*"
   660   using xy
   660   using xy
   661 proof (induction rule: rtrancl_induct)
   661 proof (induction rule: rtrancl_induct)
   662   case base
   662   case base
   663   show ?case
   663   show ?case
   664     by (simp add: assms)   
   664     by (simp add: assms)
   665 next
   665 next
   666   case (step y z)
   666   case (step y z)
   667   with xz \<open>single_valued r\<close> show ?case
   667   with xz \<open>single_valued r\<close> show ?case
   668     apply (auto simp: elim: converse_rtranclE dest: single_valuedD)
   668     apply (auto simp: elim: converse_rtranclE dest: single_valuedD)
   669     apply (blast intro: rtrancl_trans)
   669     apply (blast intro: rtrancl_trans)
   681   apply (elim exE conjE)
   681   apply (elim exE conjE)
   682   apply (drule rtranclp_trans, assumption)
   682   apply (drule rtranclp_trans, assumption)
   683   apply (drule (2) rtranclp_into_tranclp2)
   683   apply (drule (2) rtranclp_into_tranclp2)
   684   done
   684   done
   685 
   685 
       
   686 lemma rtranclp_conversep: "r\<inverse>\<inverse>\<^sup>*\<^sup>* = r\<^sup>*\<^sup>*\<inverse>\<inverse>"
       
   687   by(auto simp add: fun_eq_iff intro: rtranclp_converseI rtranclp_converseD)
       
   688 
       
   689 lemmas symp_rtranclp = sym_rtrancl[to_pred]
       
   690 
       
   691 lemmas symp_conv_conversep_eq = sym_conv_converse_eq[to_pred]
       
   692 
       
   693 lemmas rtranclp_tranclp_absorb [simp] = rtrancl_trancl_absorb[to_pred]
       
   694 lemmas tranclp_rtranclp_absorb [simp] = trancl_rtrancl_absorb[to_pred]
       
   695 lemmas rtranclp_reflclp_absorb [simp] = rtrancl_reflcl_absorb[to_pred]
       
   696 
   686 lemmas trancl_rtrancl_trancl = tranclp_rtranclp_tranclp [to_set]
   697 lemmas trancl_rtrancl_trancl = tranclp_rtranclp_tranclp [to_set]
   687 
   698 
   688 lemmas transitive_closure_trans [trans] =
   699 lemmas transitive_closure_trans [trans] =
   689   r_r_into_trancl trancl_trans rtrancl_trans
   700   r_r_into_trancl trancl_trans rtrancl_trans
   690   trancl.trancl_into_trancl trancl_into_trancl2
   701   trancl.trancl_into_trancl trancl_into_trancl2
   697   rtranclp.rtrancl_into_rtrancl converse_rtranclp_into_rtranclp
   708   rtranclp.rtrancl_into_rtrancl converse_rtranclp_into_rtranclp
   698   rtranclp_tranclp_tranclp tranclp_rtranclp_tranclp
   709   rtranclp_tranclp_tranclp tranclp_rtranclp_tranclp
   699 
   710 
   700 declare trancl_into_rtrancl [elim]
   711 declare trancl_into_rtrancl [elim]
   701 
   712 
       
   713 subsection \<open>Symmetric closure\<close>
       
   714 
       
   715 definition symclp :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool"
       
   716 where "symclp r x y \<longleftrightarrow> r x y \<or> r y x"
       
   717 
       
   718 lemma symclpI [simp, intro?]:
       
   719   shows symclpI1: "r x y \<Longrightarrow> symclp r x y"
       
   720   and symclpI2: "r y x \<Longrightarrow> symclp r x y"
       
   721 by(simp_all add: symclp_def)
       
   722 
       
   723 lemma symclpE [consumes 1, cases pred]:
       
   724   assumes "symclp r x y"
       
   725   obtains (base) "r x y" | (sym) "r y x"
       
   726 using assms by(auto simp add: symclp_def)
       
   727 
       
   728 lemma symclp_pointfree: "symclp r = sup r r\<inverse>\<inverse>"
       
   729   by(auto simp add: symclp_def fun_eq_iff)
       
   730 
       
   731 lemma symclp_greater: "r \<le> symclp r"
       
   732   by(simp add: symclp_pointfree)
       
   733 
       
   734 lemma symclp_conversep [simp]: "symclp r\<inverse>\<inverse> = symclp r"
       
   735   by(simp add: symclp_pointfree sup.commute)
       
   736 
       
   737 lemma symp_symclp [simp]: "symp (symclp r)"
       
   738   by(auto simp add: symp_def elim: symclpE intro: symclpI)
       
   739 
       
   740 lemma symp_symclp_eq: "symp r \<Longrightarrow> symclp r = r"
       
   741   by(simp add: symclp_pointfree symp_conv_conversep_eq)
       
   742 
       
   743 lemma symp_rtranclp_symclp [simp]: "symp (symclp r)\<^sup>*\<^sup>*"
       
   744   by(simp add: symp_rtranclp)
       
   745 
       
   746 lemma rtranclp_symclp_sym [sym]: "(symclp r)\<^sup>*\<^sup>* x y \<Longrightarrow> (symclp r)\<^sup>*\<^sup>* y x"
       
   747   by(rule sympD[OF symp_rtranclp_symclp])
       
   748 
       
   749 lemma symclp_idem [simp]: "symclp (symclp r) = symclp r"
       
   750   by(simp add: symclp_pointfree sup_commute converse_join)
       
   751 
       
   752 lemma reflp_rtranclp [simp]: "reflp R\<^sup>*\<^sup>*"
       
   753   using refl_rtrancl[to_pred, of R] reflp_refl_eq[of "{(x, y). R\<^sup>*\<^sup>* x y}"] by simp
   702 
   754 
   703 subsection \<open>The power operation on relations\<close>
   755 subsection \<open>The power operation on relations\<close>
   704 
   756 
   705 text \<open>\<open>R ^^ n = R O \<dots> O R\<close>, the n-fold composition of \<open>R\<close>\<close>
   757 text \<open>\<open>R ^^ n = R O \<dots> O R\<close>, the n-fold composition of \<open>R\<close>\<close>
   706 
   758 
  1270     addSolver (mk_solver "Rtrancl" Trancl_Tac.rtrancl_tac)
  1322     addSolver (mk_solver "Rtrancl" Trancl_Tac.rtrancl_tac)
  1271     addSolver (mk_solver "Tranclp" Tranclp_Tac.trancl_tac)
  1323     addSolver (mk_solver "Tranclp" Tranclp_Tac.trancl_tac)
  1272     addSolver (mk_solver "Rtranclp" Tranclp_Tac.rtrancl_tac))
  1324     addSolver (mk_solver "Rtranclp" Tranclp_Tac.rtrancl_tac))
  1273 \<close>
  1325 \<close>
  1274 
  1326 
       
  1327 lemma transp_rtranclp [simp]: "transp R\<^sup>*\<^sup>*"
       
  1328   by(auto simp add: transp_def)
  1275 
  1329 
  1276 text \<open>Optional methods.\<close>
  1330 text \<open>Optional methods.\<close>
  1277 
  1331 
  1278 method_setup trancl =
  1332 method_setup trancl =
  1279   \<open>Scan.succeed (SIMPLE_METHOD' o Trancl_Tac.trancl_tac)\<close>
  1333   \<open>Scan.succeed (SIMPLE_METHOD' o Trancl_Tac.trancl_tac)\<close>