src/HOL/Transitive_Closure.thy
changeset 12823 9d3f5056296b
parent 12691 d21db58bcdc2
child 12937 0c4fd7529467
equal deleted inserted replaced
12822:073116d65bb9 12823:9d3f5056296b
    20 consts
    20 consts
    21   rtrancl :: "('a \<times> 'a) set => ('a \<times> 'a) set"    ("(_^*)" [1000] 999)
    21   rtrancl :: "('a \<times> 'a) set => ('a \<times> 'a) set"    ("(_^*)" [1000] 999)
    22 
    22 
    23 inductive "r^*"
    23 inductive "r^*"
    24   intros
    24   intros
    25     rtrancl_refl [intro!, simp]: "(a, a) : r^*"
    25     rtrancl_refl [intro!, CPure.intro!, simp]: "(a, a) : r^*"
    26     rtrancl_into_rtrancl: "(a, b) : r^* ==> (b, c) : r ==> (a, c) : r^*"
    26     rtrancl_into_rtrancl [CPure.intro]: "(a, b) : r^* ==> (b, c) : r ==> (a, c) : r^*"
    27 
    27 
    28 constdefs
    28 constdefs
    29   trancl :: "('a \<times> 'a) set => ('a \<times> 'a) set"    ("(_^+)" [1000] 999)
    29   trancl :: "('a \<times> 'a) set => ('a \<times> 'a) set"    ("(_^+)" [1000] 999)
    30   "r^+ ==  r O rtrancl r"
    30   "r^+ ==  r O rtrancl r"
    31 
    31 
    55   apply (erule rtrancl.induct)
    55   apply (erule rtrancl.induct)
    56    apply (rule_tac [2] rtrancl_into_rtrancl)
    56    apply (rule_tac [2] rtrancl_into_rtrancl)
    57     apply blast+
    57     apply blast+
    58   done
    58   done
    59 
    59 
    60 theorem rtrancl_induct [consumes 1]:
    60 theorem rtrancl_induct [consumes 1, induct set: rtrancl]:
    61   (assumes a: "(a, b) : r^*"
    61   (assumes a: "(a, b) : r^*"
    62     and cases: "P a" "!!y z. [| (a, y) : r^*; (y, z) : r; P y |] ==> P z")
    62     and cases: "P a" "!!y z. [| (a, y) : r^*; (y, z) : r; P y |] ==> P z")
    63   "P b"
    63   "P b"
    64 proof -
    64 proof -
    65   from a have "a = a --> P b"
    65   from a have "a = a --> P b"
    66     by (induct "%x y. x = a --> P y" a b rule: rtrancl.induct)
    66     by (induct "%x y. x = a --> P y" a b) (rules intro: cases)+
    67       (rules intro: cases)+
       
    68   thus ?thesis by rules
    67   thus ?thesis by rules
    69 qed
    68 qed
    70 
    69 
    71 ML_setup {*
    70 ML_setup {*
    72   bind_thm ("rtrancl_induct2", split_rule
    71   bind_thm ("rtrancl_induct2", split_rule
    73     (read_instantiate [("a","(ax,ay)"), ("b","(bx,by)")] (thm "rtrancl_induct")));
    72     (read_instantiate [("a","(ax,ay)"), ("b","(bx,by)")] (thm "rtrancl_induct")));
    74 *}
    73 *}
    75 
    74 
    76 lemma trans_rtrancl: "trans(r^*)"
    75 lemma trans_rtrancl: "trans(r^*)"
    77   -- {* transitivity of transitive closure!! -- by induction *}
    76   -- {* transitivity of transitive closure!! -- by induction *}
    78   apply (unfold trans_def)
    77 proof (rule transI)
    79   apply safe
    78   fix x y z
    80   apply (erule_tac b = z in rtrancl_induct)
    79   assume "(x, y) \<in> r\<^sup>*"
    81    apply (blast intro: rtrancl_into_rtrancl)+
    80   assume "(y, z) \<in> r\<^sup>*"
    82   done
    81   thus "(x, z) \<in> r\<^sup>*" by induct (rules!)+
       
    82 qed
    83 
    83 
    84 lemmas rtrancl_trans = trans_rtrancl [THEN transD, standard]
    84 lemmas rtrancl_trans = trans_rtrancl [THEN transD, standard]
    85 
    85 
    86 lemma rtranclE:
    86 lemma rtranclE:
    87   "[| (a::'a,b) : r^*;  (a = b) ==> P;
    87   "[| (a::'a,b) : r^*;  (a = b) ==> P;
    98       prefer 2 apply (blast!)
    98       prefer 2 apply (blast!)
    99     apply (erule asm_rl exE disjE conjE prems)+
    99     apply (erule asm_rl exE disjE conjE prems)+
   100     done
   100     done
   101 qed
   101 qed
   102 
   102 
   103 lemmas converse_rtrancl_into_rtrancl = r_into_rtrancl [THEN rtrancl_trans, standard]
   103 lemma converse_rtrancl_into_rtrancl:
       
   104   "(a, b) \<in> r \<Longrightarrow> (b, c) \<in> r\<^sup>* \<Longrightarrow> (a, c) \<in> r\<^sup>*"
       
   105   by (rule rtrancl_trans) rules+
   104 
   106 
   105 text {*
   107 text {*
   106   \medskip More @{term "r^*"} equations and inclusions.
   108   \medskip More @{term "r^*"} equations and inclusions.
   107 *}
   109 *}
   108 
   110 
   146   apply (case_tac "a = b")
   148   apply (case_tac "a = b")
   147    apply blast
   149    apply blast
   148   apply (blast intro!: r_into_rtrancl)
   150   apply (blast intro!: r_into_rtrancl)
   149   done
   151   done
   150 
   152 
   151 lemma rtrancl_converseD: "(x, y) \<in> (r^-1)^* ==> (y, x) \<in> r^*"
   153 theorem rtrancl_converseD:
   152   apply (erule rtrancl_induct)
   154   (assumes r: "(x, y) \<in> (r^-1)^*") "(y, x) \<in> r^*"
   153    apply (rule rtrancl_refl)
   155 proof -
   154   apply (blast intro: rtrancl_trans)
   156   from r show ?thesis
   155   done
   157     by induct (rules intro: rtrancl_trans dest!: converseD)+
   156 
   158 qed
   157 lemma rtrancl_converseI: "(y, x) \<in> r^* ==> (x, y) \<in> (r^-1)^*"
   159 
   158   apply (erule rtrancl_induct)
   160 theorem rtrancl_converseI:
   159    apply (rule rtrancl_refl)
   161   (assumes r: "(y, x) \<in> r^*") "(x, y) \<in> (r^-1)^*"
   160   apply (blast intro: rtrancl_trans)
   162 proof -
   161   done
   163   from r show ?thesis
       
   164     by induct (rules intro: rtrancl_trans converseI)+
       
   165 qed
   162 
   166 
   163 lemma rtrancl_converse: "(r^-1)^* = (r^*)^-1"
   167 lemma rtrancl_converse: "(r^-1)^* = (r^*)^-1"
   164   by (fast dest!: rtrancl_converseD intro!: rtrancl_converseI)
   168   by (fast dest!: rtrancl_converseD intro!: rtrancl_converseI)
   165 
   169 
   166 lemma converse_rtrancl_induct:
   170 theorem converse_rtrancl_induct:
   167   "[| (a,b) : r^*; P(b);
   171   (assumes major: "(a, b) : r^*"
   168       !!y z.[| (y,z) : r;  (z,b) : r^*;  P(z) |] ==> P(y) |]
   172    and cases: "P b" "!!y z. [| (y, z) : r; (z, b) : r^*; P z |] ==> P y")
   169     ==> P(a)"
   173     "P a"
   170 proof -
   174 proof -
   171   assume major: "(a,b) : r^*"
   175   from rtrancl_converseI [OF major]
   172   case rule_context
   176   show ?thesis
   173   show ?thesis
   177     by induct (rules intro: cases dest!: converseD rtrancl_converseD)+
   174     apply (rule major [THEN rtrancl_converseI, THEN rtrancl_induct])
       
   175      apply assumption
       
   176     apply (blast! dest!: rtrancl_converseD)
       
   177   done
       
   178 qed
   178 qed
   179 
   179 
   180 ML_setup {*
   180 ML_setup {*
   181   bind_thm ("converse_rtrancl_induct2", split_rule
   181   bind_thm ("converse_rtrancl_induct2", split_rule
   182     (read_instantiate [("a","(ax,ay)"),("b","(bx,by)")] (thm "converse_rtrancl_induct")));
   182     (read_instantiate [("a","(ax,ay)"),("b","(bx,by)")] (thm "converse_rtrancl_induct")));
   470   rtrancl_into_rtrancl converse_rtrancl_into_rtrancl
   470   rtrancl_into_rtrancl converse_rtrancl_into_rtrancl
   471   rtrancl_trancl_trancl trancl_rtrancl_trancl
   471   rtrancl_trancl_trancl trancl_rtrancl_trancl
   472 
   472 
   473 declare trancl_into_rtrancl [elim]
   473 declare trancl_into_rtrancl [elim]
   474 
   474 
   475 declare rtrancl_induct [induct set: rtrancl]
       
   476 declare rtranclE [cases set: rtrancl]
   475 declare rtranclE [cases set: rtrancl]
   477 declare trancl_induct [induct set: trancl]
   476 declare trancl_induct [induct set: trancl]
   478 declare tranclE [cases set: trancl]
   477 declare tranclE [cases set: trancl]
   479 
   478 
   480 end
   479 end