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 |