|
1 (* Title: Turing machine's definition and its charater |
|
2 Author: XuJian <xujian817@hotmail.com> |
|
3 Maintainer: Xujian |
|
4 *) |
|
5 |
|
6 header {* Undeciablity of the {\em Halting problem} *} |
|
7 |
|
8 theory Uncomputable |
|
9 imports Turing_Hoare |
|
10 begin |
|
11 |
|
12 lemma numeral: |
|
13 shows "1 = Suc 0" |
|
14 and "2 = Suc 1" |
|
15 and "3 = Suc 2" |
|
16 and "4 = Suc 3" |
|
17 and "5 = Suc 4" |
|
18 and "6 = Suc 5" |
|
19 and "7 = Suc 6" |
|
20 and "8 = Suc 7" |
|
21 and "9 = Suc 8" |
|
22 and "10 = Suc 9" |
|
23 by arith+ |
|
24 |
|
25 text {* |
|
26 The {\em Copying} TM, which duplicates its input. |
|
27 *} |
|
28 |
|
29 definition |
|
30 tcopy_begin :: "instr list" |
|
31 where |
|
32 "tcopy_begin \<equiv> [(W0, 0), (R, 2), (R, 3), (R, 2), |
|
33 (W1, 3), (L, 4), (L, 4), (L, 0)]" |
|
34 |
|
35 definition |
|
36 tcopy_loop :: "instr list" |
|
37 where |
|
38 "tcopy_loop \<equiv> [(R, 0), (R, 2), (R, 3), (W0, 2), |
|
39 (R, 3), (R, 4), (W1, 5), (R, 4), |
|
40 (L, 6), (L, 5), (L, 6), (L, 1)]" |
|
41 |
|
42 definition |
|
43 tcopy_end :: "instr list" |
|
44 where |
|
45 "tcopy_end \<equiv> [(L, 0), (R, 2), (W1, 3), (L, 4), |
|
46 (R, 2), (R, 2), (L, 5), (W0, 4), |
|
47 (R, 0), (L, 5)]" |
|
48 |
|
49 definition |
|
50 tcopy :: "instr list" |
|
51 where |
|
52 "tcopy \<equiv> (tcopy_begin |+| tcopy_loop) |+| tcopy_end" |
|
53 |
|
54 |
|
55 (* tcopy_begin *) |
|
56 |
|
57 fun |
|
58 inv_begin0 :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
59 inv_begin1 :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
60 inv_begin2 :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
61 inv_begin3 :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
62 inv_begin4 :: "nat \<Rightarrow> tape \<Rightarrow> bool" |
|
63 where |
|
64 "inv_begin0 n (l, r) = ((n > 1 \<and> (l, r) = (Oc \<up> (n - 2), [Oc, Oc, Bk, Oc])) \<or> |
|
65 (n = 1 \<and> (l, r) = ([], [Bk, Oc, Bk, Oc])))" |
|
66 | "inv_begin1 n (l, r) = ((l, r) = ([], Oc \<up> n))" |
|
67 | "inv_begin2 n (l, r) = (\<exists> i j. i > 0 \<and> i + j = n \<and> (l, r) = (Oc \<up> i, Oc \<up> j))" |
|
68 | "inv_begin3 n (l, r) = (n > 0 \<and> (l, tl r) = (Bk # Oc \<up> n, []))" |
|
69 | "inv_begin4 n (l, r) = (n > 0 \<and> (l, r) = (Oc \<up> n, [Bk, Oc]) \<or> (l, r) = (Oc \<up> (n - 1), [Oc, Bk, Oc]))" |
|
70 |
|
71 fun inv_begin :: "nat \<Rightarrow> config \<Rightarrow> bool" |
|
72 where |
|
73 "inv_begin n (s, tp) = |
|
74 (if s = 0 then inv_begin0 n tp else |
|
75 if s = 1 then inv_begin1 n tp else |
|
76 if s = 2 then inv_begin2 n tp else |
|
77 if s = 3 then inv_begin3 n tp else |
|
78 if s = 4 then inv_begin4 n tp |
|
79 else False)" |
|
80 |
|
81 lemma [elim]: "\<lbrakk>0 < i; 0 < j\<rbrakk> \<Longrightarrow> |
|
82 \<exists>ia>0. ia + j - Suc 0 = i + j \<and> Oc # Oc \<up> i = Oc \<up> ia" |
|
83 by (rule_tac x = "Suc i" in exI, simp) |
|
84 |
|
85 lemma inv_begin_step: |
|
86 assumes "inv_begin n cf" |
|
87 and "n > 0" |
|
88 shows "inv_begin n (step0 cf tcopy_begin)" |
|
89 using assms |
|
90 unfolding tcopy_begin_def |
|
91 apply(case_tac cf) |
|
92 apply(auto simp: numeral split: if_splits) |
|
93 apply(case_tac "hd c") |
|
94 apply(auto) |
|
95 apply(case_tac c) |
|
96 apply(simp_all) |
|
97 done |
|
98 |
|
99 lemma inv_begin_steps: |
|
100 assumes "inv_begin n cf" |
|
101 and "n > 0" |
|
102 shows "inv_begin n (steps0 cf tcopy_begin stp)" |
|
103 apply(induct stp) |
|
104 apply(simp add: assms) |
|
105 apply(auto simp del: steps.simps) |
|
106 apply(rule_tac inv_begin_step) |
|
107 apply(simp_all add: assms) |
|
108 done |
|
109 |
|
110 lemma begin_partial_correctness: |
|
111 assumes "is_final (steps0 (1, [], Oc \<up> n) tcopy_begin stp)" |
|
112 shows "0 < n \<Longrightarrow> {inv_begin1 n} tcopy_begin {inv_begin0 n}" |
|
113 proof(rule_tac Hoare_haltI) |
|
114 fix l r |
|
115 assume h: "0 < n" "inv_begin1 n (l, r)" |
|
116 have "inv_begin n (steps0 (1, [], Oc \<up> n) tcopy_begin stp)" |
|
117 using h by (rule_tac inv_begin_steps) (simp_all add: inv_begin.simps) |
|
118 then show |
|
119 "\<exists>stp. is_final (steps0 (1, l, r) tcopy_begin stp) \<and> |
|
120 inv_begin0 n holds_for steps (1, l, r) (tcopy_begin, 0) stp" |
|
121 using h assms |
|
122 apply(rule_tac x = stp in exI) |
|
123 apply(case_tac "(steps0 (1, [], Oc \<up> n) tcopy_begin stp)", simp add: inv_begin.simps) |
|
124 done |
|
125 qed |
|
126 |
|
127 fun measure_begin_state :: "config \<Rightarrow> nat" |
|
128 where |
|
129 "measure_begin_state (s, l, r) = (if s = 0 then 0 else 5 - s)" |
|
130 |
|
131 fun measure_begin_step :: "config \<Rightarrow> nat" |
|
132 where |
|
133 "measure_begin_step (s, l, r) = |
|
134 (if s = 2 then length r else |
|
135 if s = 3 then (if r = [] \<or> r = [Bk] then 1 else 0) else |
|
136 if s = 4 then length l |
|
137 else 0)" |
|
138 |
|
139 definition |
|
140 "measure_begin = measures [measure_begin_state, measure_begin_step]" |
|
141 |
|
142 lemma wf_measure_begin: |
|
143 shows "wf measure_begin" |
|
144 unfolding measure_begin_def |
|
145 by auto |
|
146 |
|
147 lemma measure_begin_induct [case_names Step]: |
|
148 "\<lbrakk>\<And>n. \<not> P (f n) \<Longrightarrow> (f (Suc n), (f n)) \<in> measure_begin\<rbrakk> \<Longrightarrow> \<exists>n. P (f n)" |
|
149 using wf_measure_begin |
|
150 by (metis wf_iff_no_infinite_down_chain) |
|
151 |
|
152 lemma begin_halts: |
|
153 assumes h: "x > 0" |
|
154 shows "\<exists> stp. is_final (steps0 (1, [], Oc \<up> x) tcopy_begin stp)" |
|
155 proof (induct rule: measure_begin_induct) |
|
156 case (Step n) |
|
157 have "\<not> is_final (steps0 (1, [], Oc \<up> x) tcopy_begin n)" by fact |
|
158 moreover |
|
159 have "inv_begin x (steps0 (1, [], Oc \<up> x) tcopy_begin n)" |
|
160 by (rule_tac inv_begin_steps) (simp_all add: inv_begin.simps h) |
|
161 moreover |
|
162 obtain s l r where eq: "(steps0 (1, [], Oc \<up> x) tcopy_begin n) = (s, l, r)" |
|
163 by (metis measure_begin_state.cases) |
|
164 ultimately |
|
165 have "(step0 (s, l, r) tcopy_begin, s, l, r) \<in> measure_begin" |
|
166 apply(auto simp: measure_begin_def tcopy_begin_def numeral split: if_splits) |
|
167 apply(subgoal_tac "r = [Oc]") |
|
168 apply(auto) |
|
169 by (metis cell.exhaust list.exhaust tl.simps(2)) |
|
170 then |
|
171 show "(steps0 (1, [], Oc \<up> x) tcopy_begin (Suc n), steps0 (1, [], Oc \<up> x) tcopy_begin n) \<in> measure_begin" |
|
172 using eq by (simp only: step_red) |
|
173 qed |
|
174 |
|
175 lemma begin_correct: |
|
176 shows "0 < n \<Longrightarrow> {inv_begin1 n} tcopy_begin {inv_begin0 n}" |
|
177 using begin_partial_correctness begin_halts by blast |
|
178 |
|
179 declare tm_comp.simps [simp del] |
|
180 declare adjust.simps[simp del] |
|
181 declare shift.simps[simp del] |
|
182 declare tm_wf.simps[simp del] |
|
183 declare step.simps[simp del] |
|
184 declare steps.simps[simp del] |
|
185 |
|
186 (* tcopy_loop *) |
|
187 |
|
188 fun |
|
189 inv_loop1_loop :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
190 inv_loop1_exit :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
191 inv_loop5_loop :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
192 inv_loop5_exit :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
193 inv_loop6_loop :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
194 inv_loop6_exit :: "nat \<Rightarrow> tape \<Rightarrow> bool" |
|
195 where |
|
196 "inv_loop1_loop n (l, r) = (\<exists> i j. i + j + 1 = n \<and> (l, r) = (Oc\<up>i, Oc#Oc#Bk\<up>j @ Oc\<up>j) \<and> j > 0)" |
|
197 | "inv_loop1_exit n (l, r) = (0 < n \<and> (l, r) = ([], Bk#Oc#Bk\<up>n @ Oc\<up>n))" |
|
198 | "inv_loop5_loop x (l, r) = |
|
199 (\<exists> i j k t. i + j = Suc x \<and> i > 0 \<and> j > 0 \<and> k + t = j \<and> t > 0 \<and> (l, r) = (Oc\<up>k@Bk\<up>j@Oc\<up>i, Oc\<up>t))" |
|
200 | "inv_loop5_exit x (l, r) = |
|
201 (\<exists> i j. i + j = Suc x \<and> i > 0 \<and> j > 0 \<and> (l, r) = (Bk\<up>(j - 1)@Oc\<up>i, Bk # Oc\<up>j))" |
|
202 | "inv_loop6_loop x (l, r) = |
|
203 (\<exists> i j k t. i + j = Suc x \<and> i > 0 \<and> k + t + 1 = j \<and> (l, r) = (Bk\<up>k @ Oc\<up>i, Bk\<up>(Suc t) @ Oc\<up>j))" |
|
204 | "inv_loop6_exit x (l, r) = |
|
205 (\<exists> i j. i + j = x \<and> j > 0 \<and> (l, r) = (Oc\<up>i, Oc#Bk\<up>j @ Oc\<up>j))" |
|
206 |
|
207 fun |
|
208 inv_loop0 :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
209 inv_loop1 :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
210 inv_loop2 :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
211 inv_loop3 :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
212 inv_loop4 :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
213 inv_loop5 :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
214 inv_loop6 :: "nat \<Rightarrow> tape \<Rightarrow> bool" |
|
215 where |
|
216 "inv_loop0 n (l, r) = (0 < n \<and> (l, r) = ([Bk], Oc # Bk\<up>n @ Oc\<up>n))" |
|
217 | "inv_loop1 n (l, r) = (inv_loop1_loop n (l, r) \<or> inv_loop1_exit n (l, r))" |
|
218 | "inv_loop2 n (l, r) = (\<exists> i j any. i + j = n \<and> n > 0 \<and> i > 0 \<and> j > 0 \<and> (l, r) = (Oc\<up>i, any#Bk\<up>j@Oc\<up>j))" |
|
219 | "inv_loop3 n (l, r) = |
|
220 (\<exists> i j k t. i + j = n \<and> i > 0 \<and> j > 0 \<and> k + t = Suc j \<and> (l, r) = (Bk\<up>k@Oc\<up>i, Bk\<up>t@Oc\<up>j))" |
|
221 | "inv_loop4 n (l, r) = |
|
222 (\<exists> i j k t. i + j = n \<and> i > 0 \<and> j > 0 \<and> k + t = j \<and> (l, r) = (Oc\<up>k @ Bk\<up>(Suc j)@Oc\<up>i, Oc\<up>t))" |
|
223 | "inv_loop5 n (l, r) = (inv_loop5_loop n (l, r) \<or> inv_loop5_exit n (l, r))" |
|
224 | "inv_loop6 n (l, r) = (inv_loop6_loop n (l, r) \<or> inv_loop6_exit n (l, r))" |
|
225 |
|
226 fun inv_loop :: "nat \<Rightarrow> config \<Rightarrow> bool" |
|
227 where |
|
228 "inv_loop x (s, l, r) = |
|
229 (if s = 0 then inv_loop0 x (l, r) |
|
230 else if s = 1 then inv_loop1 x (l, r) |
|
231 else if s = 2 then inv_loop2 x (l, r) |
|
232 else if s = 3 then inv_loop3 x (l, r) |
|
233 else if s = 4 then inv_loop4 x (l, r) |
|
234 else if s = 5 then inv_loop5 x (l, r) |
|
235 else if s = 6 then inv_loop6 x (l, r) |
|
236 else False)" |
|
237 |
|
238 declare inv_loop.simps[simp del] inv_loop1.simps[simp del] |
|
239 inv_loop2.simps[simp del] inv_loop3.simps[simp del] |
|
240 inv_loop4.simps[simp del] inv_loop5.simps[simp del] |
|
241 inv_loop6.simps[simp del] |
|
242 |
|
243 lemma [elim]: "Bk # list = Oc \<up> t \<Longrightarrow> RR" |
|
244 by (case_tac t, auto) |
|
245 |
|
246 lemma [simp]: "inv_loop1 x (b, []) = False" |
|
247 by (simp add: inv_loop1.simps) |
|
248 |
|
249 lemma [elim]: "\<lbrakk>0 < x; inv_loop2 x (b, [])\<rbrakk> \<Longrightarrow> inv_loop3 x (Bk # b, [])" |
|
250 by (auto simp: inv_loop2.simps inv_loop3.simps) |
|
251 |
|
252 |
|
253 lemma [elim]: "\<lbrakk>0 < x; inv_loop3 x (b, [])\<rbrakk> \<Longrightarrow> inv_loop3 x (Bk # b, [])" |
|
254 by (auto simp: inv_loop3.simps) |
|
255 |
|
256 |
|
257 lemma [elim]: "\<lbrakk>0 < x; inv_loop4 x (b, [])\<rbrakk> \<Longrightarrow> inv_loop5 x (b, [Oc])" |
|
258 apply(auto simp: inv_loop4.simps inv_loop5.simps) |
|
259 apply(rule_tac [!] x = i in exI, |
|
260 rule_tac [!] x = "Suc j" in exI, simp_all) |
|
261 done |
|
262 |
|
263 lemma [elim]: "\<lbrakk>0 < x; inv_loop5 x ([], [])\<rbrakk> \<Longrightarrow> RR" |
|
264 by (auto simp: inv_loop4.simps inv_loop5.simps) |
|
265 |
|
266 lemma [elim]: "\<lbrakk>0 < x; inv_loop5 x (b, []); b \<noteq> []\<rbrakk> \<Longrightarrow> RR" |
|
267 by (auto simp: inv_loop4.simps inv_loop5.simps) |
|
268 |
|
269 lemma [elim]: "inv_loop6 x ([], []) \<Longrightarrow> RR" |
|
270 by (auto simp: inv_loop6.simps) |
|
271 |
|
272 lemma [elim]: "inv_loop6 x (b, []) \<Longrightarrow> RR" |
|
273 by (auto simp: inv_loop6.simps) |
|
274 |
|
275 lemma [elim]: "\<lbrakk>0 < x; inv_loop1 x (b, Bk # list)\<rbrakk> \<Longrightarrow> b = []" |
|
276 by (auto simp: inv_loop1.simps) |
|
277 |
|
278 lemma [elim]: "\<lbrakk>0 < x; inv_loop1 x (b, Bk # list)\<rbrakk> \<Longrightarrow> list = Oc # Bk \<up> x @ Oc \<up> x" |
|
279 by (auto simp: inv_loop1.simps) |
|
280 |
|
281 lemma [elim]: "\<lbrakk>0 < x; inv_loop2 x (b, Bk # list)\<rbrakk> \<Longrightarrow> inv_loop3 x (Bk # b, list)" |
|
282 apply(auto simp: inv_loop2.simps inv_loop3.simps) |
|
283 apply(rule_tac [!] x = i in exI, rule_tac [!] x = j in exI, simp_all) |
|
284 done |
|
285 |
|
286 lemma [elim]: "Bk # list = Oc \<up> j \<Longrightarrow> RR" |
|
287 by (case_tac j, simp_all) |
|
288 |
|
289 lemma [elim]: "\<lbrakk>0 < x; inv_loop3 x (b, Bk # list)\<rbrakk> \<Longrightarrow> inv_loop3 x (Bk # b, list)" |
|
290 apply(auto simp: inv_loop3.simps) |
|
291 apply(rule_tac [!] x = i in exI, |
|
292 rule_tac [!] x = j in exI, simp_all) |
|
293 apply(case_tac [!] t, auto) |
|
294 done |
|
295 |
|
296 lemma [elim]: "\<lbrakk>0 < x; inv_loop4 x (b, Bk # list)\<rbrakk> \<Longrightarrow> inv_loop5 x (b, Oc # list)" |
|
297 by (auto simp: inv_loop4.simps inv_loop5.simps) |
|
298 |
|
299 lemma [elim]: "\<lbrakk>0 < x; inv_loop5 x ([], Bk # list)\<rbrakk> \<Longrightarrow> inv_loop6 x ([], Bk # Bk # list)" |
|
300 by (auto simp: inv_loop6.simps inv_loop5.simps) |
|
301 |
|
302 lemma [simp]: "inv_loop5_loop x (b, Bk # list) = False" |
|
303 by (auto simp: inv_loop5.simps) |
|
304 |
|
305 lemma [simp]: "inv_loop6_exit x (b, Bk # list) = False" |
|
306 by (auto simp: inv_loop6.simps) |
|
307 |
|
308 declare inv_loop5_loop.simps[simp del] inv_loop5_exit.simps[simp del] |
|
309 inv_loop6_loop.simps[simp del] inv_loop6_exit.simps[simp del] |
|
310 |
|
311 lemma [elim]:"\<lbrakk>0 < x; inv_loop5_exit x (b, Bk # list); b \<noteq> []; hd b = Bk\<rbrakk> |
|
312 \<Longrightarrow> inv_loop6_loop x (tl b, Bk # Bk # list)" |
|
313 apply(simp only: inv_loop5_exit.simps inv_loop6_loop.simps ) |
|
314 apply(erule_tac exE)+ |
|
315 apply(rule_tac x = i in exI, |
|
316 rule_tac x = j in exI, |
|
317 rule_tac x = "j - Suc (Suc 0)" in exI, |
|
318 rule_tac x = "Suc 0" in exI, auto) |
|
319 apply(case_tac [!] j, simp_all) |
|
320 apply(case_tac [!] nat, simp_all) |
|
321 done |
|
322 |
|
323 lemma [simp]: "inv_loop6_loop x (b, Oc # Bk # list) = False" |
|
324 by (auto simp: inv_loop6_loop.simps) |
|
325 |
|
326 lemma [elim]: "\<lbrakk>x > 0; inv_loop5_exit x (b, Bk # list); b \<noteq> []; hd b = Oc\<rbrakk> \<Longrightarrow> |
|
327 inv_loop6_exit x (tl b, Oc # Bk # list)" |
|
328 apply(simp only: inv_loop5_exit.simps inv_loop6_exit.simps) |
|
329 apply(erule_tac exE)+ |
|
330 apply(rule_tac x = "x - 1" in exI, rule_tac x = 1 in exI, simp) |
|
331 apply(case_tac j, auto) |
|
332 apply(case_tac [!] nat, auto) |
|
333 done |
|
334 |
|
335 lemma [elim]: "\<lbrakk>0 < x; inv_loop5 x (b, Bk # list); b \<noteq> []\<rbrakk> \<Longrightarrow> inv_loop6 x (tl b, hd b # Bk # list)" |
|
336 apply(simp add: inv_loop5.simps inv_loop6.simps) |
|
337 apply(case_tac "hd b", simp_all, auto) |
|
338 done |
|
339 |
|
340 lemma [simp]: "inv_loop6 x ([], Bk # xs) = False" |
|
341 apply(simp add: inv_loop6.simps inv_loop6_loop.simps |
|
342 inv_loop6_exit.simps) |
|
343 apply(auto) |
|
344 done |
|
345 |
|
346 lemma [elim]: "\<lbrakk>0 < x; inv_loop6 x ([], Bk # list)\<rbrakk> \<Longrightarrow> inv_loop6 x ([], Bk # Bk # list)" |
|
347 by (simp) |
|
348 |
|
349 lemma [simp]: "inv_loop6_exit x (b, Bk # list) = False" |
|
350 by (simp add: inv_loop6_exit.simps) |
|
351 |
|
352 lemma [elim]: "\<lbrakk>0 < x; inv_loop6_loop x (b, Bk # list); b \<noteq> []; hd b = Bk\<rbrakk> |
|
353 \<Longrightarrow> inv_loop6_loop x (tl b, Bk # Bk # list)" |
|
354 apply(simp only: inv_loop6_loop.simps) |
|
355 apply(erule_tac exE)+ |
|
356 apply(rule_tac x = i in exI, rule_tac x = j in exI, |
|
357 rule_tac x = "k - 1" in exI, rule_tac x = "Suc t" in exI, auto) |
|
358 apply(case_tac [!] k, auto) |
|
359 done |
|
360 |
|
361 lemma [elim]: "\<lbrakk>0 < x; inv_loop6_loop x (b, Bk # list); b \<noteq> []; hd b = Oc\<rbrakk> |
|
362 \<Longrightarrow> inv_loop6_exit x (tl b, Oc # Bk # list)" |
|
363 apply(simp only: inv_loop6_loop.simps inv_loop6_exit.simps) |
|
364 apply(erule_tac exE)+ |
|
365 apply(rule_tac x = "i - 1" in exI, rule_tac x = j in exI, auto) |
|
366 apply(case_tac [!] k, auto) |
|
367 done |
|
368 |
|
369 lemma [elim]: "\<lbrakk>0 < x; inv_loop6 x (b, Bk # list); b \<noteq> []\<rbrakk> \<Longrightarrow> inv_loop6 x (tl b, hd b # Bk # list)" |
|
370 apply(simp add: inv_loop6.simps) |
|
371 apply(case_tac "hd b", simp_all, auto) |
|
372 done |
|
373 |
|
374 lemma [elim]: "\<lbrakk>0 < x; inv_loop1 x (b, Oc # list)\<rbrakk> \<Longrightarrow> inv_loop2 x (Oc # b, list)" |
|
375 apply(auto simp: inv_loop1.simps inv_loop2.simps) |
|
376 apply(rule_tac x = "Suc i" in exI, auto) |
|
377 done |
|
378 |
|
379 lemma [elim]: "\<lbrakk>0 < x; inv_loop2 x (b, Oc # list)\<rbrakk> \<Longrightarrow> inv_loop2 x (b, Bk # list)" |
|
380 by (auto simp: inv_loop2.simps) |
|
381 |
|
382 lemma [elim]: "\<lbrakk>0 < x; inv_loop3 x (b, Oc # list)\<rbrakk> \<Longrightarrow> inv_loop4 x (Oc # b, list)" |
|
383 apply(auto simp: inv_loop3.simps inv_loop4.simps) |
|
384 apply(rule_tac [!] x = i in exI, auto) |
|
385 apply(rule_tac [!] x = "Suc 0" in exI, rule_tac [!] x = "j - 1" in exI, auto) |
|
386 apply(case_tac [!] t, auto) |
|
387 apply(case_tac [!] j, auto) |
|
388 done |
|
389 |
|
390 lemma [elim]: "\<lbrakk>0 < x; inv_loop4 x (b, Oc # list)\<rbrakk> \<Longrightarrow> inv_loop4 x (Oc # b, list)" |
|
391 apply(auto simp: inv_loop4.simps) |
|
392 apply(rule_tac [!] x = "i" in exI, auto) |
|
393 apply(rule_tac [!] x = "Suc k" in exI, rule_tac [!] x = "t - 1" in exI, auto) |
|
394 apply(case_tac [!] t, simp_all) |
|
395 done |
|
396 |
|
397 lemma [simp]: "inv_loop5 x ([], list) = False" |
|
398 by (auto simp: inv_loop5.simps inv_loop5_exit.simps inv_loop5_loop.simps) |
|
399 |
|
400 lemma [simp]: "inv_loop5_exit x (b, Oc # list) = False" |
|
401 by (auto simp: inv_loop5_exit.simps) |
|
402 |
|
403 lemma [elim]: " \<lbrakk>inv_loop5_loop x (b, Oc # list); b \<noteq> []; hd b = Bk\<rbrakk> |
|
404 \<Longrightarrow> inv_loop5_exit x (tl b, Bk # Oc # list)" |
|
405 apply(simp only: inv_loop5_loop.simps inv_loop5_exit.simps) |
|
406 apply(erule_tac exE)+ |
|
407 apply(rule_tac x = i in exI, auto) |
|
408 apply(case_tac [!] k, auto) |
|
409 done |
|
410 |
|
411 lemma [elim]: "\<lbrakk>inv_loop5_loop x (b, Oc # list); b \<noteq> []; hd b = Oc\<rbrakk> |
|
412 \<Longrightarrow> inv_loop5_loop x (tl b, Oc # Oc # list)" |
|
413 apply(simp only: inv_loop5_loop.simps) |
|
414 apply(erule_tac exE)+ |
|
415 apply(rule_tac x = i in exI, rule_tac x = j in exI) |
|
416 apply(rule_tac x = "k - 1" in exI, rule_tac x = "Suc t" in exI, auto) |
|
417 apply(case_tac [!] k, auto) |
|
418 done |
|
419 |
|
420 lemma [elim]: "\<lbrakk>inv_loop5 x (b, Oc # list); b \<noteq> []\<rbrakk> \<Longrightarrow> inv_loop5 x (tl b, hd b # Oc # list)" |
|
421 apply(simp add: inv_loop5.simps) |
|
422 apply(case_tac "hd b", simp_all, auto) |
|
423 done |
|
424 |
|
425 lemma [elim]: "\<lbrakk>0 < x; inv_loop6 x ([], Oc # list)\<rbrakk> \<Longrightarrow> inv_loop1 x ([], Bk # Oc # list)" |
|
426 apply(auto simp: inv_loop6.simps inv_loop1.simps |
|
427 inv_loop6_loop.simps inv_loop6_exit.simps) |
|
428 done |
|
429 |
|
430 lemma [elim]: "\<lbrakk>0 < x; inv_loop6 x (b, Oc # list); b \<noteq> []\<rbrakk> |
|
431 \<Longrightarrow> inv_loop1 x (tl b, hd b # Oc # list)" |
|
432 apply(auto simp: inv_loop6.simps inv_loop1.simps |
|
433 inv_loop6_loop.simps inv_loop6_exit.simps) |
|
434 done |
|
435 |
|
436 lemma inv_loop_step: |
|
437 "\<lbrakk>inv_loop x cf; x > 0\<rbrakk> \<Longrightarrow> inv_loop x (step cf (tcopy_loop, 0))" |
|
438 apply(case_tac cf, case_tac c, case_tac [2] aa) |
|
439 apply(auto simp: inv_loop.simps step.simps tcopy_loop_def numeral split: if_splits) |
|
440 done |
|
441 |
|
442 lemma inv_loop_steps: |
|
443 "\<lbrakk>inv_loop x cf; x > 0\<rbrakk> \<Longrightarrow> inv_loop x (steps cf (tcopy_loop, 0) stp)" |
|
444 apply(induct stp, simp add: steps.simps, simp) |
|
445 apply(erule_tac inv_loop_step, simp) |
|
446 done |
|
447 |
|
448 fun loop_stage :: "config \<Rightarrow> nat" |
|
449 where |
|
450 "loop_stage (s, l, r) = (if s = 0 then 0 |
|
451 else (Suc (length (takeWhile (\<lambda>a. a = Oc) (rev l @ r)))))" |
|
452 |
|
453 fun loop_state :: "config \<Rightarrow> nat" |
|
454 where |
|
455 "loop_state (s, l, r) = (if s = 2 \<and> hd r = Oc then 0 |
|
456 else if s = 1 then 1 |
|
457 else 10 - s)" |
|
458 |
|
459 fun loop_step :: "config \<Rightarrow> nat" |
|
460 where |
|
461 "loop_step (s, l, r) = (if s = 3 then length r |
|
462 else if s = 4 then length r |
|
463 else if s = 5 then length l |
|
464 else if s = 6 then length l |
|
465 else 0)" |
|
466 |
|
467 definition measure_loop :: "(config \<times> config) set" |
|
468 where |
|
469 "measure_loop = measures [loop_stage, loop_state, loop_step]" |
|
470 |
|
471 lemma wf_measure_loop: "wf measure_loop" |
|
472 unfolding measure_loop_def |
|
473 by (auto) |
|
474 |
|
475 lemma measure_loop_induct [case_names Step]: |
|
476 "\<lbrakk>\<And>n. \<not> P (f n) \<Longrightarrow> (f (Suc n), (f n)) \<in> measure_loop\<rbrakk> \<Longrightarrow> \<exists>n. P (f n)" |
|
477 using wf_measure_loop |
|
478 by (metis wf_iff_no_infinite_down_chain) |
|
479 |
|
480 |
|
481 |
|
482 lemma [simp]: "inv_loop2 x ([], b) = False" |
|
483 by (auto simp: inv_loop2.simps) |
|
484 |
|
485 lemma [simp]: "inv_loop2 x (l', []) = False" |
|
486 by (auto simp: inv_loop2.simps) |
|
487 |
|
488 lemma [simp]: "inv_loop3 x (b, []) = False" |
|
489 by (auto simp: inv_loop3.simps) |
|
490 |
|
491 lemma [simp]: "inv_loop4 x ([], b) = False" |
|
492 by (auto simp: inv_loop4.simps) |
|
493 |
|
494 |
|
495 lemma [elim]: |
|
496 "\<lbrakk>inv_loop4 x (l', []); l' \<noteq> []; x > 0; |
|
497 length (takeWhile (\<lambda>a. a = Oc) (rev l' @ [Oc])) \<noteq> |
|
498 length (takeWhile (\<lambda>a. a = Oc) (rev l'))\<rbrakk> |
|
499 \<Longrightarrow> length (takeWhile (\<lambda>a. a = Oc) (rev l' @ [Oc])) < length (takeWhile (\<lambda>a. a = Oc) (rev l'))" |
|
500 apply(auto simp: inv_loop4.simps) |
|
501 apply(case_tac [!] j, simp_all add: List.takeWhile_tail) |
|
502 done |
|
503 |
|
504 |
|
505 lemma [elim]: |
|
506 "\<lbrakk>inv_loop4 x (l', Bk # list); l' \<noteq> []; 0 < x; |
|
507 length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Oc # list)) \<noteq> |
|
508 length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Bk # list))\<rbrakk> |
|
509 \<Longrightarrow> length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Oc # list)) < |
|
510 length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Bk # list))" |
|
511 by (auto simp: inv_loop4.simps) |
|
512 |
|
513 lemma takeWhile_replicate_append: |
|
514 "P a \<Longrightarrow> takeWhile P (a\<up>x @ ys) = a\<up>x @ takeWhile P ys" |
|
515 by (induct x, auto) |
|
516 |
|
517 lemma takeWhile_replicate: |
|
518 "P a \<Longrightarrow> takeWhile P (a\<up>x) = a\<up>x" |
|
519 by (induct x, auto) |
|
520 |
|
521 lemma [elim]: |
|
522 "\<lbrakk>inv_loop5 x (l', Bk # list); l' \<noteq> []; 0 < x; |
|
523 length (takeWhile (\<lambda>a. a = Oc) (rev (tl l') @ hd l' # Bk # list)) \<noteq> |
|
524 length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Bk # list))\<rbrakk> |
|
525 \<Longrightarrow> length (takeWhile (\<lambda>a. a = Oc) (rev (tl l') @ hd l' # Bk # list)) < |
|
526 length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Bk # list))" |
|
527 apply(auto simp: inv_loop5.simps inv_loop5_exit.simps) |
|
528 apply(case_tac [!] j, simp_all) |
|
529 apply(case_tac [!] "nat", simp_all) |
|
530 apply(case_tac nata, simp_all add: List.takeWhile_tail) |
|
531 apply(simp add: takeWhile_replicate_append takeWhile_replicate) |
|
532 apply(case_tac nata, simp_all add: List.takeWhile_tail) |
|
533 done |
|
534 |
|
535 lemma [elim]: "\<lbrakk>inv_loop1 x (l', Oc # list)\<rbrakk> \<Longrightarrow> hd list = Oc" |
|
536 by (auto simp: inv_loop1.simps) |
|
537 |
|
538 lemma [elim]: |
|
539 "\<lbrakk>inv_loop6 x (l', Bk # list); l' \<noteq> []; 0 < x; |
|
540 length (takeWhile (\<lambda>a. a = Oc) (rev (tl l') @ hd l' # Bk # list)) \<noteq> |
|
541 length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Bk # list))\<rbrakk> |
|
542 \<Longrightarrow> length (takeWhile (\<lambda>a. a = Oc) (rev (tl l') @ hd l' # Bk # list)) < |
|
543 length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Bk # list))" |
|
544 apply(auto simp: inv_loop6.simps) |
|
545 apply(case_tac l', simp_all) |
|
546 done |
|
547 |
|
548 lemma [elim]: |
|
549 "\<lbrakk>inv_loop2 x (l', Oc # list); l' \<noteq> []; 0 < x\<rbrakk> \<Longrightarrow> |
|
550 length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Bk # list)) < |
|
551 length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Oc # list))" |
|
552 apply(auto simp: inv_loop2.simps) |
|
553 apply(simp_all add: takeWhile_tail takeWhile_replicate_append |
|
554 takeWhile_replicate) |
|
555 done |
|
556 |
|
557 lemma [elim]: |
|
558 "\<lbrakk>inv_loop5 x (l', Oc # list); l' \<noteq> []; 0 < x; |
|
559 length (takeWhile (\<lambda>a. a = Oc) (rev (tl l') @ hd l' # Oc # list)) \<noteq> |
|
560 length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Oc # list))\<rbrakk> |
|
561 \<Longrightarrow> length (takeWhile (\<lambda>a. a = Oc) (rev (tl l') @ hd l' # Oc # list)) < |
|
562 length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Oc # list))" |
|
563 apply(auto simp: inv_loop5.simps) |
|
564 apply(case_tac l', auto) |
|
565 done |
|
566 |
|
567 lemma[elim]: |
|
568 "\<lbrakk>inv_loop6 x (l', Oc # list); l' \<noteq> []; 0 < x; |
|
569 length (takeWhile (\<lambda>a. a = Oc) (rev (tl l') @ hd l' # Oc # list)) |
|
570 \<noteq> length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Oc # list))\<rbrakk> |
|
571 \<Longrightarrow> length (takeWhile (\<lambda>a. a = Oc) (rev (tl l') @ hd l' # Oc # list)) < |
|
572 length (takeWhile (\<lambda>a. a = Oc) (rev l' @ Oc # list))" |
|
573 apply(case_tac l') |
|
574 apply(auto simp: inv_loop6.simps) |
|
575 done |
|
576 |
|
577 lemma loop_halts: |
|
578 assumes h: "n > 0" "inv_loop n (1, l, r)" |
|
579 shows "\<exists> stp. is_final (steps0 (1, l, r) tcopy_loop stp)" |
|
580 proof (induct rule: measure_loop_induct) |
|
581 case (Step stp) |
|
582 have "\<not> is_final (steps0 (1, l, r) tcopy_loop stp)" by fact |
|
583 moreover |
|
584 have "inv_loop n (steps0 (1, l, r) tcopy_loop stp)" |
|
585 by (rule_tac inv_loop_steps) (simp_all only: h) |
|
586 moreover |
|
587 obtain s l' r' where eq: "(steps0 (1, l, r) tcopy_loop stp) = (s, l', r')" |
|
588 by (metis measure_begin_state.cases) |
|
589 ultimately |
|
590 have "(step0 (s, l', r') tcopy_loop, s, l', r') \<in> measure_loop" |
|
591 using h(1) |
|
592 apply(case_tac r') |
|
593 apply(case_tac [2] a) |
|
594 apply(auto simp: inv_loop.simps step.simps tcopy_loop_def numeral measure_loop_def split: if_splits) |
|
595 done |
|
596 then |
|
597 show "(steps0 (1, l, r) tcopy_loop (Suc stp), steps0 (1, l, r) tcopy_loop stp) \<in> measure_loop" |
|
598 using eq by (simp only: step_red) |
|
599 qed |
|
600 |
|
601 lemma loop_correct: |
|
602 shows "0 < n \<Longrightarrow> {inv_loop1 n} tcopy_loop {inv_loop0 n}" |
|
603 using assms |
|
604 proof(rule_tac Hoare_haltI) |
|
605 fix l r |
|
606 assume h: "0 < n" "inv_loop1 n (l, r)" |
|
607 then obtain stp where k: "is_final (steps0 (1, l, r) tcopy_loop stp)" |
|
608 using loop_halts |
|
609 apply(simp add: inv_loop.simps) |
|
610 apply(blast) |
|
611 done |
|
612 moreover |
|
613 have "inv_loop n (steps0 (1, l, r) tcopy_loop stp)" |
|
614 using h |
|
615 by (rule_tac inv_loop_steps) (simp_all add: inv_loop.simps) |
|
616 ultimately show |
|
617 "\<exists>stp. is_final (steps0 (1, l, r) tcopy_loop stp) \<and> |
|
618 inv_loop0 n holds_for steps0 (1, l, r) tcopy_loop stp" |
|
619 using h(1) |
|
620 apply(rule_tac x = stp in exI) |
|
621 apply(case_tac "(steps0 (1, l, r) tcopy_loop stp)") |
|
622 apply(simp add: inv_loop.simps) |
|
623 done |
|
624 qed |
|
625 |
|
626 |
|
627 |
|
628 |
|
629 (* tcopy_end *) |
|
630 |
|
631 fun |
|
632 inv_end5_loop :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
633 inv_end5_exit :: "nat \<Rightarrow> tape \<Rightarrow> bool" |
|
634 where |
|
635 "inv_end5_loop x (l, r) = |
|
636 (\<exists> i j. i + j = x \<and> x > 0 \<and> j > 0 \<and> l = Oc\<up>i @ [Bk] \<and> r = Oc\<up>j @ Bk # Oc\<up>x)" |
|
637 | "inv_end5_exit x (l, r) = (x > 0 \<and> l = [] \<and> r = Bk # Oc\<up>x @ Bk # Oc\<up>x)" |
|
638 |
|
639 fun |
|
640 inv_end0 :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
641 inv_end1 :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
642 inv_end2 :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
643 inv_end3 :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
644 inv_end4 :: "nat \<Rightarrow> tape \<Rightarrow> bool" and |
|
645 inv_end5 :: "nat \<Rightarrow> tape \<Rightarrow> bool" |
|
646 where |
|
647 "inv_end0 n (l, r) = (n > 0 \<and> (l, r) = ([Bk], Oc\<up>n @ Bk # Oc\<up>n))" |
|
648 | "inv_end1 n (l, r) = (n > 0 \<and> (l, r) = ([Bk], Oc # Bk\<up>n @ Oc\<up>n))" |
|
649 | "inv_end2 n (l, r) = (\<exists> i j. i + j = Suc n \<and> n > 0 \<and> l = Oc\<up>i @ [Bk] \<and> r = Bk\<up>j @ Oc\<up>n)" |
|
650 | "inv_end3 n (l, r) = |
|
651 (\<exists> i j. n > 0 \<and> i + j = n \<and> l = Oc\<up>i @ [Bk] \<and> r = Oc # Bk\<up>j@ Oc\<up>n)" |
|
652 | "inv_end4 n (l, r) = (\<exists> any. n > 0 \<and> l = Oc\<up>n @ [Bk] \<and> r = any#Oc\<up>n)" |
|
653 | "inv_end5 n (l, r) = (inv_end5_loop n (l, r) \<or> inv_end5_exit n (l, r))" |
|
654 |
|
655 fun |
|
656 inv_end :: "nat \<Rightarrow> config \<Rightarrow> bool" |
|
657 where |
|
658 "inv_end n (s, l, r) = (if s = 0 then inv_end0 n (l, r) |
|
659 else if s = 1 then inv_end1 n (l, r) |
|
660 else if s = 2 then inv_end2 n (l, r) |
|
661 else if s = 3 then inv_end3 n (l, r) |
|
662 else if s = 4 then inv_end4 n (l, r) |
|
663 else if s = 5 then inv_end5 n (l, r) |
|
664 else False)" |
|
665 |
|
666 declare inv_end.simps[simp del] inv_end1.simps[simp del] |
|
667 inv_end0.simps[simp del] inv_end2.simps[simp del] |
|
668 inv_end3.simps[simp del] inv_end4.simps[simp del] |
|
669 inv_end5.simps[simp del] |
|
670 |
|
671 lemma [simp]: "inv_end1 x (b, []) = False" |
|
672 by (auto simp: inv_end1.simps) |
|
673 |
|
674 lemma [simp]: "inv_end2 x (b, []) = False" |
|
675 by (auto simp: inv_end2.simps) |
|
676 |
|
677 lemma [simp]: "inv_end3 x (b, []) = False" |
|
678 by (auto simp: inv_end3.simps) |
|
679 |
|
680 lemma [simp]: "inv_end4 x (b, []) = False" |
|
681 by (auto simp: inv_end4.simps) |
|
682 |
|
683 lemma [simp]: "inv_end5 x (b, []) = False" |
|
684 by (auto simp: inv_end5.simps) |
|
685 |
|
686 lemma [simp]: "inv_end1 x ([], list) = False" |
|
687 by (auto simp: inv_end1.simps) |
|
688 |
|
689 lemma [elim]: "\<lbrakk>0 < x; inv_end1 x (b, Bk # list); b \<noteq> []\<rbrakk> |
|
690 \<Longrightarrow> inv_end0 x (tl b, hd b # Bk # list)" |
|
691 by (auto simp: inv_end1.simps inv_end0.simps) |
|
692 |
|
693 lemma [elim]: "\<lbrakk>0 < x; inv_end2 x (b, Bk # list)\<rbrakk> |
|
694 \<Longrightarrow> inv_end3 x (b, Oc # list)" |
|
695 apply(auto simp: inv_end2.simps inv_end3.simps) |
|
696 apply(rule_tac x = "j - 1" in exI) |
|
697 apply(case_tac j, simp_all) |
|
698 apply(case_tac x, simp_all) |
|
699 done |
|
700 |
|
701 lemma [elim]: "\<lbrakk>0 < x; inv_end3 x (b, Bk # list)\<rbrakk> \<Longrightarrow> inv_end2 x (Bk # b, list)" |
|
702 by (auto simp: inv_end2.simps inv_end3.simps) |
|
703 |
|
704 lemma [elim]: "\<lbrakk>0 < x; inv_end4 x ([], Bk # list)\<rbrakk> \<Longrightarrow> |
|
705 inv_end5 x ([], Bk # Bk # list)" |
|
706 by (auto simp: inv_end4.simps inv_end5.simps) |
|
707 |
|
708 lemma [elim]: "\<lbrakk>0 < x; inv_end4 x (b, Bk # list); b \<noteq> []\<rbrakk> \<Longrightarrow> |
|
709 inv_end5 x (tl b, hd b # Bk # list)" |
|
710 apply(auto simp: inv_end4.simps inv_end5.simps) |
|
711 apply(rule_tac x = 1 in exI, simp) |
|
712 done |
|
713 |
|
714 lemma [elim]: "\<lbrakk>0 < x; inv_end5 x (b, Bk # list)\<rbrakk> \<Longrightarrow> inv_end0 x (Bk # b, list)" |
|
715 apply(auto simp: inv_end5.simps inv_end0.simps) |
|
716 apply(case_tac [!] j, simp_all) |
|
717 done |
|
718 |
|
719 lemma [elim]: "\<lbrakk>0 < x; inv_end1 x (b, Oc # list)\<rbrakk> \<Longrightarrow> inv_end2 x (Oc # b, list)" |
|
720 by (auto simp: inv_end1.simps inv_end2.simps) |
|
721 |
|
722 lemma [elim]: "\<lbrakk>0 < x; inv_end2 x ([], Oc # list)\<rbrakk> \<Longrightarrow> |
|
723 inv_end4 x ([], Bk # Oc # list)" |
|
724 by (auto simp: inv_end2.simps inv_end4.simps) |
|
725 |
|
726 lemma [elim]: "\<lbrakk>0 < x; inv_end2 x (b, Oc # list); b \<noteq> []\<rbrakk> \<Longrightarrow> |
|
727 inv_end4 x (tl b, hd b # Oc # list)" |
|
728 apply(auto simp: inv_end2.simps inv_end4.simps) |
|
729 apply(case_tac [!] j, simp_all) |
|
730 done |
|
731 |
|
732 lemma [elim]: "\<lbrakk>0 < x; inv_end3 x (b, Oc # list)\<rbrakk> \<Longrightarrow> inv_end2 x (Oc # b, list)" |
|
733 by (auto simp: inv_end2.simps inv_end3.simps) |
|
734 |
|
735 lemma [elim]: "\<lbrakk>0 < x; inv_end4 x (b, Oc # list)\<rbrakk> \<Longrightarrow> inv_end4 x (b, Bk # list)" |
|
736 by (auto simp: inv_end2.simps inv_end4.simps) |
|
737 |
|
738 lemma [elim]: "\<lbrakk>0 < x; inv_end5 x ([], Oc # list)\<rbrakk> \<Longrightarrow> inv_end5 x ([], Bk # Oc # list)" |
|
739 by (auto simp: inv_end2.simps inv_end5.simps) |
|
740 |
|
741 declare inv_end5_loop.simps[simp del] |
|
742 inv_end5_exit.simps[simp del] |
|
743 |
|
744 lemma [simp]: "inv_end5_exit x (b, Oc # list) = False" |
|
745 by (auto simp: inv_end5_exit.simps) |
|
746 |
|
747 lemma [simp]: "inv_end5_loop x (tl b, Bk # Oc # list) = False" |
|
748 apply(auto simp: inv_end5_loop.simps) |
|
749 apply(case_tac [!] j, simp_all) |
|
750 done |
|
751 |
|
752 lemma [elim]: |
|
753 "\<lbrakk>0 < x; inv_end5_loop x (b, Oc # list); b \<noteq> []; hd b = Bk\<rbrakk> \<Longrightarrow> |
|
754 inv_end5_exit x (tl b, Bk # Oc # list)" |
|
755 apply(auto simp: inv_end5_loop.simps inv_end5_exit.simps) |
|
756 apply(case_tac [!] i, simp_all) |
|
757 done |
|
758 |
|
759 lemma [elim]: |
|
760 "\<lbrakk>0 < x; inv_end5_loop x (b, Oc # list); b \<noteq> []; hd b = Oc\<rbrakk> \<Longrightarrow> |
|
761 inv_end5_loop x (tl b, Oc # Oc # list)" |
|
762 apply(simp only: inv_end5_loop.simps inv_end5_exit.simps) |
|
763 apply(erule_tac exE)+ |
|
764 apply(rule_tac x = "i - 1" in exI, |
|
765 rule_tac x = "Suc j" in exI, auto) |
|
766 apply(case_tac [!] i, simp_all) |
|
767 done |
|
768 |
|
769 lemma [elim]: "\<lbrakk>0 < x; inv_end5 x (b, Oc # list); b \<noteq> []\<rbrakk> \<Longrightarrow> |
|
770 inv_end5 x (tl b, hd b # Oc # list)" |
|
771 apply(simp add: inv_end2.simps inv_end5.simps) |
|
772 apply(case_tac "hd b", simp_all, auto) |
|
773 done |
|
774 |
|
775 lemma inv_end_step: |
|
776 "\<lbrakk>x > 0; inv_end x cf\<rbrakk> \<Longrightarrow> inv_end x (step cf (tcopy_end, 0))" |
|
777 apply(case_tac cf, case_tac c, case_tac [2] aa) |
|
778 apply(auto simp: inv_end.simps step.simps tcopy_end_def numeral split: if_splits) |
|
779 done |
|
780 |
|
781 lemma inv_end_steps: |
|
782 "\<lbrakk>x > 0; inv_end x cf\<rbrakk> \<Longrightarrow> inv_end x (steps cf (tcopy_end, 0) stp)" |
|
783 apply(induct stp, simp add:steps.simps, simp) |
|
784 apply(erule_tac inv_end_step, simp) |
|
785 done |
|
786 |
|
787 fun end_state :: "config \<Rightarrow> nat" |
|
788 where |
|
789 "end_state (s, l, r) = |
|
790 (if s = 0 then 0 |
|
791 else if s = 1 then 5 |
|
792 else if s = 2 \<or> s = 3 then 4 |
|
793 else if s = 4 then 3 |
|
794 else if s = 5 then 2 |
|
795 else 0)" |
|
796 |
|
797 fun end_stage :: "config \<Rightarrow> nat" |
|
798 where |
|
799 "end_stage (s, l, r) = |
|
800 (if s = 2 \<or> s = 3 then (length r) else 0)" |
|
801 |
|
802 fun end_step :: "config \<Rightarrow> nat" |
|
803 where |
|
804 "end_step (s, l, r) = |
|
805 (if s = 4 then (if hd r = Oc then 1 else 0) |
|
806 else if s = 5 then length l |
|
807 else if s = 2 then 1 |
|
808 else if s = 3 then 0 |
|
809 else 0)" |
|
810 |
|
811 definition end_LE :: "(config \<times> config) set" |
|
812 where |
|
813 "end_LE = measures [end_state, end_stage, end_step]" |
|
814 |
|
815 lemma wf_end_le: "wf end_LE" |
|
816 unfolding end_LE_def |
|
817 by (auto) |
|
818 |
|
819 lemma [simp]: "inv_end5 x ([], Oc # list) = False" |
|
820 by (auto simp: inv_end5.simps inv_end5_loop.simps) |
|
821 |
|
822 lemma halt_lemma: |
|
823 "\<lbrakk>wf LE; \<forall>n. (\<not> P (f n) \<longrightarrow> (f (Suc n), (f n)) \<in> LE)\<rbrakk> \<Longrightarrow> \<exists>n. P (f n)" |
|
824 by (metis wf_iff_no_infinite_down_chain) |
|
825 |
|
826 lemma end_halt: |
|
827 "\<lbrakk>x > 0; inv_end x (Suc 0, l, r)\<rbrakk> \<Longrightarrow> |
|
828 \<exists> stp. is_final (steps (Suc 0, l, r) (tcopy_end, 0) stp)" |
|
829 proof(rule_tac LE = end_LE in halt_lemma) |
|
830 show "wf end_LE" by(intro wf_end_le) |
|
831 next |
|
832 assume great: "0 < x" |
|
833 and inv_start: "inv_end x (Suc 0, l, r)" |
|
834 show "\<forall>n. \<not> is_final (steps (Suc 0, l, r) (tcopy_end, 0) n) \<longrightarrow> |
|
835 (steps (Suc 0, l, r) (tcopy_end, 0) (Suc n), steps (Suc 0, l, r) (tcopy_end, 0) n) \<in> end_LE" |
|
836 proof(rule_tac allI, rule_tac impI) |
|
837 fix n |
|
838 assume notfinal: "\<not> is_final (steps (Suc 0, l, r) (tcopy_end, 0) n)" |
|
839 obtain s' l' r' where d: "steps (Suc 0, l, r) (tcopy_end, 0) n = (s', l', r')" |
|
840 apply(case_tac "steps (Suc 0, l, r) (tcopy_end, 0) n", auto) |
|
841 done |
|
842 hence "inv_end x (s', l', r') \<and> s' \<noteq> 0" |
|
843 using great inv_start notfinal |
|
844 apply(drule_tac stp = n in inv_end_steps, auto) |
|
845 done |
|
846 hence "(step (s', l', r') (tcopy_end, 0), s', l', r') \<in> end_LE" |
|
847 apply(case_tac r', case_tac [2] a) |
|
848 apply(auto simp: inv_end.simps step.simps tcopy_end_def numeral end_LE_def split: if_splits) |
|
849 done |
|
850 thus "(steps (Suc 0, l, r) (tcopy_end, 0) (Suc n), |
|
851 steps (Suc 0, l, r) (tcopy_end, 0) n) \<in> end_LE" |
|
852 using d |
|
853 by simp |
|
854 qed |
|
855 qed |
|
856 |
|
857 lemma end_correct: |
|
858 "n > 0 \<Longrightarrow> {inv_end1 n} tcopy_end {inv_end0 n}" |
|
859 proof(rule_tac Hoare_haltI) |
|
860 fix l r |
|
861 assume h: "0 < n" |
|
862 "inv_end1 n (l, r)" |
|
863 then have "\<exists> stp. is_final (steps0 (1, l, r) tcopy_end stp)" |
|
864 by (simp add: end_halt inv_end.simps) |
|
865 then obtain stp where "is_final (steps0 (1, l, r) tcopy_end stp)" .. |
|
866 moreover have "inv_end n (steps0 (1, l, r) tcopy_end stp)" |
|
867 apply(rule_tac inv_end_steps) |
|
868 using h by(simp_all add: inv_end.simps) |
|
869 ultimately show |
|
870 "\<exists>stp. is_final (steps (1, l, r) (tcopy_end, 0) stp) \<and> |
|
871 inv_end0 n holds_for steps (1, l, r) (tcopy_end, 0) stp" |
|
872 using h |
|
873 apply(rule_tac x = stp in exI) |
|
874 apply(case_tac "(steps0 (1, l, r) tcopy_end stp)") |
|
875 apply(simp add: inv_end.simps) |
|
876 done |
|
877 qed |
|
878 |
|
879 (* tcopy *) |
|
880 |
|
881 lemma [intro]: "tm_wf (tcopy_begin, 0)" |
|
882 by (auto simp: tm_wf.simps tcopy_begin_def) |
|
883 |
|
884 lemma [intro]: "tm_wf (tcopy_loop, 0)" |
|
885 by (auto simp: tm_wf.simps tcopy_loop_def) |
|
886 |
|
887 lemma [intro]: "tm_wf (tcopy_end, 0)" |
|
888 by (auto simp: tm_wf.simps tcopy_end_def) |
|
889 |
|
890 lemma tcopy_correct1: |
|
891 assumes "0 < x" |
|
892 shows "{inv_begin1 x} tcopy {inv_end0 x}" |
|
893 proof - |
|
894 have "{inv_begin1 x} tcopy_begin {inv_begin0 x}" |
|
895 by (metis assms begin_correct) |
|
896 moreover |
|
897 have "inv_begin0 x \<mapsto> inv_loop1 x" |
|
898 unfolding assert_imp_def |
|
899 unfolding inv_begin0.simps inv_loop1.simps |
|
900 unfolding inv_loop1_loop.simps inv_loop1_exit.simps |
|
901 apply(auto simp add: numeral Cons_eq_append_conv) |
|
902 by (rule_tac x = "Suc 0" in exI, auto) |
|
903 ultimately have "{inv_begin1 x} tcopy_begin {inv_loop1 x}" |
|
904 by (rule_tac Hoare_consequence) (auto) |
|
905 moreover |
|
906 have "{inv_loop1 x} tcopy_loop {inv_loop0 x}" |
|
907 by (metis assms loop_correct) |
|
908 ultimately |
|
909 have "{inv_begin1 x} (tcopy_begin |+| tcopy_loop) {inv_loop0 x}" |
|
910 by (rule_tac Hoare_plus_halt) (auto) |
|
911 moreover |
|
912 have "{inv_end1 x} tcopy_end {inv_end0 x}" |
|
913 by (metis assms end_correct) |
|
914 moreover |
|
915 have "inv_loop0 x = inv_end1 x" |
|
916 by(auto simp: inv_end1.simps inv_loop1.simps assert_imp_def) |
|
917 ultimately |
|
918 show "{inv_begin1 x} tcopy {inv_end0 x}" |
|
919 unfolding tcopy_def |
|
920 by (rule_tac Hoare_plus_halt) (auto) |
|
921 qed |
|
922 |
|
923 abbreviation (input) |
|
924 "pre_tcopy n \<equiv> \<lambda>tp. tp = ([]::cell list, <(n::nat)>)" |
|
925 abbreviation (input) |
|
926 "post_tcopy n \<equiv> \<lambda>tp. tp= ([Bk], <(n, n::nat)>)" |
|
927 |
|
928 lemma tcopy_correct: |
|
929 shows "{pre_tcopy n} tcopy {post_tcopy n}" |
|
930 proof - |
|
931 have "{inv_begin1 (Suc n)} tcopy {inv_end0 (Suc n)}" |
|
932 by (rule tcopy_correct1) (simp) |
|
933 moreover |
|
934 have "pre_tcopy n = inv_begin1 (Suc n)" |
|
935 by (auto simp add: tape_of_nl_abv tape_of_nat_abv) |
|
936 moreover |
|
937 have "inv_end0 (Suc n) = post_tcopy n" |
|
938 by (auto simp add: inv_end0.simps tape_of_nat_abv tape_of_nat_pair) |
|
939 ultimately |
|
940 show "{pre_tcopy n} tcopy {post_tcopy n}" |
|
941 by simp |
|
942 qed |
|
943 |
|
944 |
|
945 section {* The {\em Dithering} Turing Machine *} |
|
946 |
|
947 text {* |
|
948 The {\em Dithering} TM, when the input is @{text "1"}, it will loop forever, otherwise, it will |
|
949 terminate. |
|
950 *} |
|
951 |
|
952 definition dither :: "instr list" |
|
953 where |
|
954 "dither \<equiv> [(W0, 1), (R, 2), (L, 1), (L, 0)] " |
|
955 |
|
956 (* invariants of dither *) |
|
957 abbreviation (input) |
|
958 "dither_halt_inv \<equiv> \<lambda>tp. \<exists>k. tp = (Bk \<up> k, <1::nat>)" |
|
959 |
|
960 abbreviation (input) |
|
961 "dither_unhalt_inv \<equiv> \<lambda>tp. \<exists>k. tp = (Bk \<up> k, <0::nat>)" |
|
962 |
|
963 lemma dither_loops_aux: |
|
964 "(steps0 (1, Bk \<up> m, [Oc]) dither stp = (1, Bk \<up> m, [Oc])) \<or> |
|
965 (steps0 (1, Bk \<up> m, [Oc]) dither stp = (2, Oc # Bk \<up> m, []))" |
|
966 apply(induct stp) |
|
967 apply(auto simp: steps.simps step.simps dither_def numeral tape_of_nat_abv) |
|
968 done |
|
969 |
|
970 lemma dither_loops: |
|
971 shows "{dither_unhalt_inv} dither \<up>" |
|
972 apply(rule Hoare_unhaltI) |
|
973 using dither_loops_aux |
|
974 apply(auto simp add: numeral tape_of_nat_abv) |
|
975 by (metis Suc_neq_Zero is_final_eq) |
|
976 |
|
977 lemma dither_halts_aux: |
|
978 shows "steps0 (1, Bk \<up> m, [Oc, Oc]) dither 2 = (0, Bk \<up> m, [Oc, Oc])" |
|
979 unfolding dither_def |
|
980 by (simp add: steps.simps step.simps numeral) |
|
981 |
|
982 lemma dither_halts: |
|
983 shows "{dither_halt_inv} dither {dither_halt_inv}" |
|
984 apply(rule Hoare_haltI) |
|
985 using dither_halts_aux |
|
986 apply(auto simp add: tape_of_nat_abv) |
|
987 by (metis (lifting, mono_tags) holds_for.simps is_final_eq prod.cases) |
|
988 |
|
989 |
|
990 section {* The diagnal argument below shows the undecidability of Halting problem *} |
|
991 |
|
992 text {* |
|
993 @{text "haltP tp x"} means TM @{text "tp"} terminates on input @{text "x"} |
|
994 and the final configuration is standard. |
|
995 *} |
|
996 |
|
997 definition haltP :: "tprog0 \<Rightarrow> nat list \<Rightarrow> bool" |
|
998 where |
|
999 "haltP p ns \<equiv> {(\<lambda>tp. tp = ([], <ns>))} p {(\<lambda>tp. (\<exists>k n l. tp = (Bk \<up> k, <n::nat> @ Bk \<up> l)))}" |
|
1000 |
|
1001 lemma [intro, simp]: "tm_wf0 tcopy" |
|
1002 by (auto simp: tcopy_def) |
|
1003 |
|
1004 lemma [intro, simp]: "tm_wf0 dither" |
|
1005 by (auto simp: tm_wf.simps dither_def) |
|
1006 |
|
1007 text {* |
|
1008 The following locale specifies that TM @{text "H"} can be used to solve |
|
1009 the {\em Halting Problem} and @{text "False"} is going to be derived |
|
1010 under this locale. Therefore, the undecidability of {\em Halting Problem} |
|
1011 is established. |
|
1012 *} |
|
1013 |
|
1014 locale uncomputable = |
|
1015 -- {* The coding function of TM, interestingly, the detailed definition of this |
|
1016 funciton @{text "code"} does not affect the final result. *} |
|
1017 fixes code :: "instr list \<Rightarrow> nat" |
|
1018 -- {* |
|
1019 The TM @{text "H"} is the one which is assummed being able to solve the Halting problem. |
|
1020 *} |
|
1021 and H :: "instr list" |
|
1022 assumes h_wf[intro]: "tm_wf0 H" |
|
1023 -- {* |
|
1024 The following two assumptions specifies that @{text "H"} does solve the Halting problem. |
|
1025 *} |
|
1026 and h_case: |
|
1027 "\<And> M ns. haltP M ns \<Longrightarrow> {(\<lambda>tp. tp = ([Bk], <(code M, ns)>))} H {(\<lambda>tp. \<exists>k. tp = (Bk \<up> k, <0::nat>))}" |
|
1028 and nh_case: |
|
1029 "\<And> M ns. \<not> haltP M ns \<Longrightarrow> {(\<lambda>tp. tp = ([Bk], <(code M, ns)>))} H {(\<lambda>tp. \<exists>k. tp = (Bk \<up> k, <1::nat>))}" |
|
1030 begin |
|
1031 |
|
1032 (* invariants for H *) |
|
1033 abbreviation (input) |
|
1034 "pre_H_inv M ns \<equiv> \<lambda>tp. tp = ([Bk], <(code M, ns::nat list)>)" |
|
1035 |
|
1036 abbreviation (input) |
|
1037 "post_H_halt_inv \<equiv> \<lambda>tp. \<exists>k. tp = (Bk \<up> k, <1::nat>)" |
|
1038 |
|
1039 abbreviation (input) |
|
1040 "post_H_unhalt_inv \<equiv> \<lambda>tp. \<exists>k. tp = (Bk \<up> k, <0::nat>)" |
|
1041 |
|
1042 |
|
1043 lemma H_halt_inv: |
|
1044 assumes "\<not> haltP M ns" |
|
1045 shows "{pre_H_inv M ns} H {post_H_halt_inv}" |
|
1046 using assms nh_case by auto |
|
1047 |
|
1048 lemma H_unhalt_inv: |
|
1049 assumes "haltP M ns" |
|
1050 shows "{pre_H_inv M ns} H {post_H_unhalt_inv}" |
|
1051 using assms h_case by auto |
|
1052 |
|
1053 (* TM that produces the contradiction and its code *) |
|
1054 |
|
1055 definition |
|
1056 "tcontra \<equiv> (tcopy |+| H) |+| dither" |
|
1057 abbreviation |
|
1058 "code_tcontra \<equiv> code tcontra" |
|
1059 |
|
1060 (* assume tcontra does not halt on its code *) |
|
1061 lemma tcontra_unhalt: |
|
1062 assumes "\<not> haltP tcontra [code tcontra]" |
|
1063 shows "False" |
|
1064 proof - |
|
1065 (* invariants *) |
|
1066 def P1 \<equiv> "\<lambda>tp. tp = ([]::cell list, <code_tcontra>)" |
|
1067 def P2 \<equiv> "\<lambda>tp. tp = ([Bk], <(code_tcontra, code_tcontra)>)" |
|
1068 def P3 \<equiv> "\<lambda>tp. \<exists>k. tp = (Bk \<up> k, <1::nat>)" |
|
1069 |
|
1070 (* |
|
1071 {P1} tcopy {P2} {P2} H {P3} |
|
1072 ---------------------------- |
|
1073 {P1} (tcopy |+| H) {P3} {P3} dither {P3} |
|
1074 ------------------------------------------------ |
|
1075 {P1} tcontra {P3} |
|
1076 *) |
|
1077 |
|
1078 have H_wf: "tm_wf0 (tcopy |+| H)" by auto |
|
1079 |
|
1080 (* {P1} (tcopy |+| H) {P3} *) |
|
1081 have first: "{P1} (tcopy |+| H) {P3}" |
|
1082 proof (cases rule: Hoare_plus_halt) |
|
1083 case A_halt (* of tcopy *) |
|
1084 show "{P1} tcopy {P2}" unfolding P1_def P2_def |
|
1085 by (rule tcopy_correct) |
|
1086 next |
|
1087 case B_halt (* of H *) |
|
1088 show "{P2} H {P3}" |
|
1089 unfolding P2_def P3_def |
|
1090 using H_halt_inv[OF assms] |
|
1091 by (simp add: tape_of_nat_pair tape_of_nl_abv) |
|
1092 qed (simp) |
|
1093 |
|
1094 (* {P3} dither {P3} *) |
|
1095 have second: "{P3} dither {P3}" unfolding P3_def |
|
1096 by (rule dither_halts) |
|
1097 |
|
1098 (* {P1} tcontra {P3} *) |
|
1099 have "{P1} tcontra {P3}" |
|
1100 unfolding tcontra_def |
|
1101 by (rule Hoare_plus_halt[OF first second H_wf]) |
|
1102 |
|
1103 with assms show "False" |
|
1104 unfolding P1_def P3_def |
|
1105 unfolding haltP_def |
|
1106 unfolding Hoare_halt_def |
|
1107 apply(auto) |
|
1108 apply(drule_tac x = n in spec) |
|
1109 apply(case_tac "steps0 (Suc 0, [], <code tcontra>) tcontra n") |
|
1110 apply(auto simp add: tape_of_nl_abv) |
|
1111 by (metis append_Nil2 replicate_0) |
|
1112 qed |
|
1113 |
|
1114 (* asumme tcontra halts on its code *) |
|
1115 lemma tcontra_halt: |
|
1116 assumes "haltP tcontra [code tcontra]" |
|
1117 shows "False" |
|
1118 proof - |
|
1119 (* invariants *) |
|
1120 def P1 \<equiv> "\<lambda>tp. tp = ([]::cell list, <code_tcontra>)" |
|
1121 def P2 \<equiv> "\<lambda>tp. tp = ([Bk], <(code_tcontra, code_tcontra)>)" |
|
1122 def Q3 \<equiv> "\<lambda>tp. \<exists>k. tp = (Bk \<up> k, <0::nat>)" |
|
1123 |
|
1124 (* |
|
1125 {P1} tcopy {P2} {P2} H {Q3} |
|
1126 ---------------------------- |
|
1127 {P1} (tcopy |+| H) {Q3} {Q3} dither loops |
|
1128 ------------------------------------------------ |
|
1129 {P1} tcontra loops |
|
1130 *) |
|
1131 |
|
1132 have H_wf: "tm_wf0 (tcopy |+| H)" by auto |
|
1133 |
|
1134 (* {P1} (tcopy |+| H) {Q3} *) |
|
1135 have first: "{P1} (tcopy |+| H) {Q3}" |
|
1136 proof (cases rule: Hoare_plus_halt) |
|
1137 case A_halt (* of tcopy *) |
|
1138 show "{P1} tcopy {P2}" unfolding P1_def P2_def |
|
1139 by (rule tcopy_correct) |
|
1140 next |
|
1141 case B_halt (* of H *) |
|
1142 then show "{P2} H {Q3}" |
|
1143 unfolding P2_def Q3_def using H_unhalt_inv[OF assms] |
|
1144 by(simp add: tape_of_nat_pair tape_of_nl_abv) |
|
1145 qed (simp) |
|
1146 |
|
1147 (* {P3} dither loops *) |
|
1148 have second: "{Q3} dither \<up>" unfolding Q3_def |
|
1149 by (rule dither_loops) |
|
1150 |
|
1151 (* {P1} tcontra loops *) |
|
1152 have "{P1} tcontra \<up>" |
|
1153 unfolding tcontra_def |
|
1154 by (rule Hoare_plus_unhalt[OF first second H_wf]) |
|
1155 |
|
1156 with assms show "False" |
|
1157 unfolding P1_def |
|
1158 unfolding haltP_def |
|
1159 unfolding Hoare_halt_def Hoare_unhalt_def |
|
1160 by (auto simp add: tape_of_nl_abv) |
|
1161 qed |
|
1162 |
|
1163 |
|
1164 text {* |
|
1165 @{text "False"} can finally derived. |
|
1166 *} |
|
1167 |
|
1168 lemma false: "False" |
|
1169 using tcontra_halt tcontra_unhalt |
|
1170 by auto |
|
1171 |
|
1172 end |
|
1173 |
|
1174 declare replicate_Suc[simp del] |
|
1175 |
|
1176 |
|
1177 end |
|
1178 |