1 (* Title: HOL/Proofs/Lambda/Commutation.thy |
1 (* Title: HOL/Proofs/Lambda/Commutation.thy |
2 Author: Tobias Nipkow |
2 Author: Tobias Nipkow |
3 Copyright 1995 TU Muenchen |
3 Copyright 1995 TU Muenchen |
4 *) |
4 *) |
5 |
5 |
6 section {* Abstract commutation and confluence notions *} |
6 section \<open>Abstract commutation and confluence notions\<close> |
7 |
7 |
8 theory Commutation |
8 theory Commutation |
9 imports Main |
9 imports Main |
10 begin |
10 begin |
11 |
11 |
12 declare [[syntax_ambiguity_warning = false]] |
12 declare [[syntax_ambiguity_warning = false]] |
13 |
13 |
14 |
14 |
15 subsection {* Basic definitions *} |
15 subsection \<open>Basic definitions\<close> |
16 |
16 |
17 definition |
17 definition |
18 square :: "['a => 'a => bool, 'a => 'a => bool, 'a => 'a => bool, 'a => 'a => bool] => bool" where |
18 square :: "['a => 'a => bool, 'a => 'a => bool, 'a => 'a => bool, 'a => 'a => bool] => bool" where |
19 "square R S T U = |
19 "square R S T U = |
20 (\<forall>x y. R x y --> (\<forall>z. S x z --> (\<exists>u. T y u \<and> U z u)))" |
20 (\<forall>x y. R x y --> (\<forall>z. S x z --> (\<exists>u. T y u \<and> U z u)))" |
35 abbreviation |
35 abbreviation |
36 confluent :: "('a => 'a => bool) => bool" where |
36 confluent :: "('a => 'a => bool) => bool" where |
37 "confluent R == diamond (R^**)" |
37 "confluent R == diamond (R^**)" |
38 |
38 |
39 |
39 |
40 subsection {* Basic lemmas *} |
40 subsection \<open>Basic lemmas\<close> |
41 |
41 |
42 subsubsection {* @{text "square"} *} |
42 subsubsection \<open>\<open>square\<close>\<close> |
43 |
43 |
44 lemma square_sym: "square R S T U ==> square S R U T" |
44 lemma square_sym: "square R S T U ==> square S R U T" |
45 apply (unfold square_def) |
45 apply (unfold square_def) |
46 apply blast |
46 apply blast |
47 done |
47 done |
72 apply (unfold commute_def) |
72 apply (unfold commute_def) |
73 apply (fastforce dest: square_reflcl square_sym [THEN square_rtrancl]) |
73 apply (fastforce dest: square_reflcl square_sym [THEN square_rtrancl]) |
74 done |
74 done |
75 |
75 |
76 |
76 |
77 subsubsection {* @{text "commute"} *} |
77 subsubsection \<open>\<open>commute\<close>\<close> |
78 |
78 |
79 lemma commute_sym: "commute R S ==> commute S R" |
79 lemma commute_sym: "commute R S ==> commute S R" |
80 apply (unfold commute_def) |
80 apply (unfold commute_def) |
81 apply (blast intro: square_sym) |
81 apply (blast intro: square_sym) |
82 done |
82 done |
91 apply (unfold commute_def square_def) |
91 apply (unfold commute_def square_def) |
92 apply blast |
92 apply blast |
93 done |
93 done |
94 |
94 |
95 |
95 |
96 subsubsection {* @{text "diamond"}, @{text "confluence"}, and @{text "union"} *} |
96 subsubsection \<open>\<open>diamond\<close>, \<open>confluence\<close>, and \<open>union\<close>\<close> |
97 |
97 |
98 lemma diamond_Un: |
98 lemma diamond_Un: |
99 "[| diamond R; diamond S; commute R S |] ==> diamond (sup R S)" |
99 "[| diamond R; diamond S; commute R S |] ==> diamond (sup R S)" |
100 apply (unfold diamond_def) |
100 apply (unfold diamond_def) |
101 apply (blast intro: commute_Un commute_sym) |
101 apply (blast intro: commute_Un commute_sym) |
123 apply (force intro: diamond_confluent |
123 apply (force intro: diamond_confluent |
124 dest: rtranclp_subset [symmetric]) |
124 dest: rtranclp_subset [symmetric]) |
125 done |
125 done |
126 |
126 |
127 |
127 |
128 subsection {* Church-Rosser *} |
128 subsection \<open>Church-Rosser\<close> |
129 |
129 |
130 lemma Church_Rosser_confluent: "Church_Rosser R = confluent R" |
130 lemma Church_Rosser_confluent: "Church_Rosser R = confluent R" |
131 apply (unfold square_def commute_def diamond_def Church_Rosser_def) |
131 apply (unfold square_def commute_def diamond_def Church_Rosser_def) |
132 apply (tactic {* safe_tac (put_claset HOL_cs @{context}) *}) |
132 apply (tactic \<open>safe_tac (put_claset HOL_cs @{context})\<close>) |
133 apply (tactic {* |
133 apply (tactic \<open> |
134 blast_tac (put_claset HOL_cs @{context} addIs |
134 blast_tac (put_claset HOL_cs @{context} addIs |
135 [@{thm sup_ge2} RS @{thm rtranclp_mono} RS @{thm predicate2D} RS @{thm rtranclp_trans}, |
135 [@{thm sup_ge2} RS @{thm rtranclp_mono} RS @{thm predicate2D} RS @{thm rtranclp_trans}, |
136 @{thm rtranclp_converseI}, @{thm conversepI}, |
136 @{thm rtranclp_converseI}, @{thm conversepI}, |
137 @{thm sup_ge1} RS @{thm rtranclp_mono} RS @{thm predicate2D}]) 1 *}) |
137 @{thm sup_ge1} RS @{thm rtranclp_mono} RS @{thm predicate2D}]) 1\<close>) |
138 apply (erule rtranclp_induct) |
138 apply (erule rtranclp_induct) |
139 apply blast |
139 apply blast |
140 apply (blast del: rtranclp.rtrancl_refl intro: rtranclp_trans) |
140 apply (blast del: rtranclp.rtrancl_refl intro: rtranclp_trans) |
141 done |
141 done |
142 |
142 |
143 |
143 |
144 subsection {* Newman's lemma *} |
144 subsection \<open>Newman's lemma\<close> |
145 |
145 |
146 text {* Proof by Stefan Berghofer *} |
146 text \<open>Proof by Stefan Berghofer\<close> |
147 |
147 |
148 theorem newman: |
148 theorem newman: |
149 assumes wf: "wfP (R\<inverse>\<inverse>)" |
149 assumes wf: "wfP (R\<inverse>\<inverse>)" |
150 and lc: "\<And>a b c. R a b \<Longrightarrow> R a c \<Longrightarrow> |
150 and lc: "\<And>a b c. R a b \<Longrightarrow> R a c \<Longrightarrow> |
151 \<exists>d. R\<^sup>*\<^sup>* b d \<and> R\<^sup>*\<^sup>* c d" |
151 \<exists>d. R\<^sup>*\<^sup>* b d \<and> R\<^sup>*\<^sup>* c d" |
187 with cw show ?thesis by iprover |
187 with cw show ?thesis by iprover |
188 qed |
188 qed |
189 qed |
189 qed |
190 qed |
190 qed |
191 |
191 |
192 text {* |
192 text \<open> |
193 Alternative version. Partly automated by Tobias |
193 Alternative version. Partly automated by Tobias |
194 Nipkow. Takes 2 minutes (2002). |
194 Nipkow. Takes 2 minutes (2002). |
195 |
195 |
196 This is the maximal amount of automation possible using @{text blast}. |
196 This is the maximal amount of automation possible using \<open>blast\<close>. |
197 *} |
197 \<close> |
198 |
198 |
199 theorem newman': |
199 theorem newman': |
200 assumes wf: "wfP (R\<inverse>\<inverse>)" |
200 assumes wf: "wfP (R\<inverse>\<inverse>)" |
201 and lc: "\<And>a b c. R a b \<Longrightarrow> R a c \<Longrightarrow> |
201 and lc: "\<And>a b c. R a b \<Longrightarrow> R a c \<Longrightarrow> |
202 \<exists>d. R\<^sup>*\<^sup>* b d \<and> R\<^sup>*\<^sup>* c d" |
202 \<exists>d. R\<^sup>*\<^sup>* b d \<and> R\<^sup>*\<^sup>* c d" |
203 shows "\<And>b c. R\<^sup>*\<^sup>* a b \<Longrightarrow> R\<^sup>*\<^sup>* a c \<Longrightarrow> |
203 shows "\<And>b c. R\<^sup>*\<^sup>* a b \<Longrightarrow> R\<^sup>*\<^sup>* a c \<Longrightarrow> |
204 \<exists>d. R\<^sup>*\<^sup>* b d \<and> R\<^sup>*\<^sup>* c d" |
204 \<exists>d. R\<^sup>*\<^sup>* b d \<and> R\<^sup>*\<^sup>* c d" |
205 using wf |
205 using wf |
206 proof induct |
206 proof induct |
207 case (less x b c) |
207 case (less x b c) |
208 note IH = `\<And>y b c. \<lbrakk>R\<inverse>\<inverse> y x; R\<^sup>*\<^sup>* y b; R\<^sup>*\<^sup>* y c\<rbrakk> |
208 note IH = \<open>\<And>y b c. \<lbrakk>R\<inverse>\<inverse> y x; R\<^sup>*\<^sup>* y b; R\<^sup>*\<^sup>* y c\<rbrakk> |
209 \<Longrightarrow> \<exists>d. R\<^sup>*\<^sup>* b d \<and> R\<^sup>*\<^sup>* c d` |
209 \<Longrightarrow> \<exists>d. R\<^sup>*\<^sup>* b d \<and> R\<^sup>*\<^sup>* c d\<close> |
210 have xc: "R\<^sup>*\<^sup>* x c" by fact |
210 have xc: "R\<^sup>*\<^sup>* x c" by fact |
211 have xb: "R\<^sup>*\<^sup>* x b" by fact |
211 have xb: "R\<^sup>*\<^sup>* x b" by fact |
212 thus ?case |
212 thus ?case |
213 proof (rule converse_rtranclpE) |
213 proof (rule converse_rtranclpE) |
214 assume "x = b" |
214 assume "x = b" |
235 dest: IH [OF conversepI, OF xy] IH [OF conversepI, OF xy']) |
235 dest: IH [OF conversepI, OF xy] IH [OF conversepI, OF xy']) |
236 qed |
236 qed |
237 qed |
237 qed |
238 qed |
238 qed |
239 |
239 |
240 text {* |
240 text \<open> |
241 Using the coherent logic prover, the proof of the induction step |
241 Using the coherent logic prover, the proof of the induction step |
242 is completely automatic. |
242 is completely automatic. |
243 *} |
243 \<close> |
244 |
244 |
245 lemma eq_imp_rtranclp: "x = y \<Longrightarrow> r\<^sup>*\<^sup>* x y" |
245 lemma eq_imp_rtranclp: "x = y \<Longrightarrow> r\<^sup>*\<^sup>* x y" |
246 by simp |
246 by simp |
247 |
247 |
248 theorem newman'': |
248 theorem newman'': |
252 shows "\<And>b c. R\<^sup>*\<^sup>* a b \<Longrightarrow> R\<^sup>*\<^sup>* a c \<Longrightarrow> |
252 shows "\<And>b c. R\<^sup>*\<^sup>* a b \<Longrightarrow> R\<^sup>*\<^sup>* a c \<Longrightarrow> |
253 \<exists>d. R\<^sup>*\<^sup>* b d \<and> R\<^sup>*\<^sup>* c d" |
253 \<exists>d. R\<^sup>*\<^sup>* b d \<and> R\<^sup>*\<^sup>* c d" |
254 using wf |
254 using wf |
255 proof induct |
255 proof induct |
256 case (less x b c) |
256 case (less x b c) |
257 note IH = `\<And>y b c. \<lbrakk>R\<inverse>\<inverse> y x; R\<^sup>*\<^sup>* y b; R\<^sup>*\<^sup>* y c\<rbrakk> |
257 note IH = \<open>\<And>y b c. \<lbrakk>R\<inverse>\<inverse> y x; R\<^sup>*\<^sup>* y b; R\<^sup>*\<^sup>* y c\<rbrakk> |
258 \<Longrightarrow> \<exists>d. R\<^sup>*\<^sup>* b d \<and> R\<^sup>*\<^sup>* c d` |
258 \<Longrightarrow> \<exists>d. R\<^sup>*\<^sup>* b d \<and> R\<^sup>*\<^sup>* c d\<close> |
259 show ?case |
259 show ?case |
260 by (coherent |
260 by (coherent |
261 `R\<^sup>*\<^sup>* x c` `R\<^sup>*\<^sup>* x b` |
261 \<open>R\<^sup>*\<^sup>* x c\<close> \<open>R\<^sup>*\<^sup>* x b\<close> |
262 refl [where 'a='a] sym |
262 refl [where 'a='a] sym |
263 eq_imp_rtranclp |
263 eq_imp_rtranclp |
264 r_into_rtranclp [of R] |
264 r_into_rtranclp [of R] |
265 rtranclp_trans |
265 rtranclp_trans |
266 lc IH [OF conversepI] |
266 lc IH [OF conversepI] |