|
1 theory UF |
|
2 imports Main rec_def turing_basic GCD abacus |
|
3 begin |
|
4 |
|
5 text {* |
|
6 This theory file constructs the Universal Function @{text "rec_F"}, which is the UTM defined |
|
7 in terms of recursive functions. This @{text "rec_F"} is essentially an |
|
8 interpreter of Turing Machines. Once the correctness of @{text "rec_F"} is established, |
|
9 UTM can easil be obtained by compling @{text "rec_F"} into the corresponding Turing Machine. |
|
10 *} |
|
11 |
|
12 |
|
13 section {* The construction of component functions *} |
|
14 |
|
15 text {* |
|
16 This section constructs a set of component functions used to construct @{text "rec_F"}. |
|
17 *} |
|
18 |
|
19 text {* |
|
20 The recursive function used to do arithmatic addition. |
|
21 *} |
|
22 definition rec_add :: "recf" |
|
23 where |
|
24 "rec_add \<equiv> Pr 1 (id 1 0) (Cn 3 s [id 3 2])" |
|
25 |
|
26 text {* |
|
27 The recursive function used to do arithmatic multiplication. |
|
28 *} |
|
29 definition rec_mult :: "recf" |
|
30 where |
|
31 "rec_mult = Pr 1 z (Cn 3 rec_add [id 3 0, id 3 2])" |
|
32 |
|
33 text {* |
|
34 The recursive function used to do arithmatic precede. |
|
35 *} |
|
36 definition rec_pred :: "recf" |
|
37 where |
|
38 "rec_pred = Cn 1 (Pr 1 z (id 3 1)) [id 1 0, id 1 0]" |
|
39 |
|
40 text {* |
|
41 The recursive function used to do arithmatic subtraction. |
|
42 *} |
|
43 definition rec_minus :: "recf" |
|
44 where |
|
45 "rec_minus = Pr 1 (id 1 0) (Cn 3 rec_pred [id 3 2])" |
|
46 |
|
47 text {* |
|
48 @{text "constn n"} is the recursive function which computes |
|
49 nature number @{text "n"}. |
|
50 *} |
|
51 fun constn :: "nat \<Rightarrow> recf" |
|
52 where |
|
53 "constn 0 = z" | |
|
54 "constn (Suc n) = Cn 1 s [constn n]" |
|
55 |
|
56 |
|
57 text {* |
|
58 Signal function, which returns 1 when the input argument is greater than @{text "0"}. |
|
59 *} |
|
60 definition rec_sg :: "recf" |
|
61 where |
|
62 "rec_sg = Cn 1 rec_minus [constn 1, |
|
63 Cn 1 rec_minus [constn 1, id 1 0]]" |
|
64 |
|
65 text {* |
|
66 @{text "rec_less"} compares its two arguments, returns @{text "1"} if |
|
67 the first is less than the second; otherwise returns @{text "0"}. |
|
68 *} |
|
69 definition rec_less :: "recf" |
|
70 where |
|
71 "rec_less = Cn 2 rec_sg [Cn 2 rec_minus [id 2 1, id 2 0]]" |
|
72 |
|
73 text {* |
|
74 @{text "rec_not"} inverse its argument: returns @{text "1"} when the |
|
75 argument is @{text "0"}; returns @{text "0"} otherwise. |
|
76 *} |
|
77 definition rec_not :: "recf" |
|
78 where |
|
79 "rec_not = Cn 1 rec_minus [constn 1, id 1 0]" |
|
80 |
|
81 text {* |
|
82 @{text "rec_eq"} compares its two arguments: returns @{text "1"} |
|
83 if they are equal; return @{text "0"} otherwise. |
|
84 *} |
|
85 definition rec_eq :: "recf" |
|
86 where |
|
87 "rec_eq = Cn 2 rec_minus [Cn 2 (constn 1) [id 2 0], |
|
88 Cn 2 rec_add [Cn 2 rec_minus [id 2 0, id 2 1], |
|
89 Cn 2 rec_minus [id 2 1, id 2 0]]]" |
|
90 |
|
91 text {* |
|
92 @{text "rec_conj"} computes the conjunction of its two arguments, |
|
93 returns @{text "1"} if both of them are non-zero; returns @{text "0"} |
|
94 otherwise. |
|
95 *} |
|
96 definition rec_conj :: "recf" |
|
97 where |
|
98 "rec_conj = Cn 2 rec_sg [Cn 2 rec_mult [id 2 0, id 2 1]] " |
|
99 |
|
100 text {* |
|
101 @{text "rec_disj"} computes the disjunction of its two arguments, |
|
102 returns @{text "0"} if both of them are zero; returns @{text "0"} |
|
103 otherwise. |
|
104 *} |
|
105 definition rec_disj :: "recf" |
|
106 where |
|
107 "rec_disj = Cn 2 rec_sg [Cn 2 rec_add [id 2 0, id 2 1]]" |
|
108 |
|
109 |
|
110 text {* |
|
111 Computes the arity of recursive function. |
|
112 *} |
|
113 |
|
114 fun arity :: "recf \<Rightarrow> nat" |
|
115 where |
|
116 "arity z = 1" |
|
117 | "arity s = 1" |
|
118 | "arity (id m n) = m" |
|
119 | "arity (Cn n f gs) = n" |
|
120 | "arity (Pr n f g) = Suc n" |
|
121 | "arity (Mn n f) = n" |
|
122 |
|
123 text {* |
|
124 @{text "get_fstn_args n (Suc k)"} returns |
|
125 @{text "[id n 0, id n 1, id n 2, \<dots>, id n k]"}, |
|
126 the effect of which is to take out the first @{text "Suc k"} |
|
127 arguments out of the @{text "n"} input arguments. |
|
128 *} |
|
129 (* get_fstn_args *) |
|
130 fun get_fstn_args :: "nat \<Rightarrow> nat \<Rightarrow> recf list" |
|
131 where |
|
132 "get_fstn_args n 0 = []" |
|
133 | "get_fstn_args n (Suc y) = get_fstn_args n y @ [id n y]" |
|
134 |
|
135 text {* |
|
136 @{text "rec_sigma f"} returns the recursive functions which |
|
137 sums up the results of @{text "f"}: |
|
138 \[ |
|
139 (rec\_sigma f)(x, y) = f(x, 0) + f(x, 1) + \cdots + f(x, y) |
|
140 \] |
|
141 *} |
|
142 fun rec_sigma :: "recf \<Rightarrow> recf" |
|
143 where |
|
144 "rec_sigma rf = |
|
145 (let vl = arity rf in |
|
146 Pr (vl - 1) (Cn (vl - 1) rf (get_fstn_args (vl - 1) (vl - 1) @ |
|
147 [Cn (vl - 1) (constn 0) [id (vl - 1) 0]])) |
|
148 (Cn (Suc vl) rec_add [id (Suc vl) vl, |
|
149 Cn (Suc vl) rf (get_fstn_args (Suc vl) (vl - 1) |
|
150 @ [Cn (Suc vl) s [id (Suc vl) (vl - 1)]])]))" |
|
151 |
|
152 text {* |
|
153 @{text "rec_exec"} is the interpreter function for |
|
154 reursive functions. The function is defined such that |
|
155 it always returns meaningful results for primitive recursive |
|
156 functions. |
|
157 *} |
|
158 function rec_exec :: "recf \<Rightarrow> nat list \<Rightarrow> nat" |
|
159 where |
|
160 "rec_exec z xs = 0" | |
|
161 "rec_exec s xs = (Suc (xs ! 0))" | |
|
162 "rec_exec (id m n) xs = (xs ! n)" | |
|
163 "rec_exec (Cn n f gs) xs = |
|
164 (let ys = (map (\<lambda> a. rec_exec a xs) gs) in |
|
165 rec_exec f ys)" | |
|
166 "rec_exec (Pr n f g) xs = |
|
167 (if last xs = 0 then |
|
168 rec_exec f (butlast xs) |
|
169 else rec_exec g (butlast xs @ [last xs - 1] @ |
|
170 [rec_exec (Pr n f g) (butlast xs @ [last xs - 1])]))" | |
|
171 "rec_exec (Mn n f) xs = (LEAST x. rec_exec f (xs @ [x]) = 0)" |
|
172 by pat_completeness auto |
|
173 termination |
|
174 proof |
|
175 show "wf (measures [\<lambda> (r, xs). size r, (\<lambda> (r, xs). last xs)])" |
|
176 by auto |
|
177 next |
|
178 fix n f gs xs x |
|
179 assume "(x::recf) \<in> set gs" |
|
180 thus "((x, xs), Cn n f gs, xs) \<in> |
|
181 measures [\<lambda>(r, xs). size r, \<lambda>(r, xs). last xs]" |
|
182 by(induct gs, auto) |
|
183 next |
|
184 fix n f gs xs x |
|
185 assume "x = map (\<lambda>a. rec_exec a xs) gs" |
|
186 "\<And>x. x \<in> set gs \<Longrightarrow> rec_exec_dom (x, xs)" |
|
187 thus "((f, x), Cn n f gs, xs) \<in> |
|
188 measures [\<lambda>(r, xs). size r, \<lambda>(r, xs). last xs]" |
|
189 by(auto) |
|
190 next |
|
191 fix n f g xs |
|
192 show "((f, butlast xs), Pr n f g, xs) \<in> |
|
193 measures [\<lambda>(r, xs). size r, \<lambda>(r, xs). last xs]" |
|
194 by auto |
|
195 next |
|
196 fix n f g xs |
|
197 assume "last xs \<noteq> (0::nat)" thus |
|
198 "((Pr n f g, butlast xs @ [last xs - 1]), Pr n f g, xs) |
|
199 \<in> measures [\<lambda>(r, xs). size r, \<lambda>(r, xs). last xs]" |
|
200 by auto |
|
201 next |
|
202 fix n f g xs |
|
203 show "((g, butlast xs @ [last xs - 1] @ [rec_exec (Pr n f g) (butlast xs @ [last xs - 1])]), |
|
204 Pr n f g, xs) \<in> measures [\<lambda>(r, xs). size r, \<lambda>(r, xs). last xs]" |
|
205 by auto |
|
206 next |
|
207 fix n f xs x |
|
208 show "((f, xs @ [x]), Mn n f, xs) \<in> |
|
209 measures [\<lambda>(r, xs). size r, \<lambda>(r, xs). last xs]" |
|
210 by auto |
|
211 qed |
|
212 |
|
213 declare rec_exec.simps[simp del] constn.simps[simp del] |
|
214 |
|
215 text {* |
|
216 Correctness of @{text "rec_add"}. |
|
217 *} |
|
218 lemma add_lemma: "\<And> x y. rec_exec rec_add [x, y] = x + y" |
|
219 by(induct_tac y, auto simp: rec_add_def rec_exec.simps) |
|
220 |
|
221 text {* |
|
222 Correctness of @{text "rec_mult"}. |
|
223 *} |
|
224 lemma mult_lemma: "\<And> x y. rec_exec rec_mult [x, y] = x * y" |
|
225 by(induct_tac y, auto simp: rec_mult_def rec_exec.simps add_lemma) |
|
226 |
|
227 text {* |
|
228 Correctness of @{text "rec_pred"}. |
|
229 *} |
|
230 lemma pred_lemma: "\<And> x. rec_exec rec_pred [x] = x - 1" |
|
231 by(induct_tac x, auto simp: rec_pred_def rec_exec.simps) |
|
232 |
|
233 text {* |
|
234 Correctness of @{text "rec_minus"}. |
|
235 *} |
|
236 lemma minus_lemma: "\<And> x y. rec_exec rec_minus [x, y] = x - y" |
|
237 by(induct_tac y, auto simp: rec_exec.simps rec_minus_def pred_lemma) |
|
238 |
|
239 text {* |
|
240 Correctness of @{text "rec_sg"}. |
|
241 *} |
|
242 lemma sg_lemma: "\<And> x. rec_exec rec_sg [x] = (if x = 0 then 0 else 1)" |
|
243 by(auto simp: rec_sg_def minus_lemma rec_exec.simps constn.simps) |
|
244 |
|
245 text {* |
|
246 Correctness of @{text "constn"}. |
|
247 *} |
|
248 lemma constn_lemma: "rec_exec (constn n) [x] = n" |
|
249 by(induct n, auto simp: rec_exec.simps constn.simps) |
|
250 |
|
251 text {* |
|
252 Correctness of @{text "rec_less"}. |
|
253 *} |
|
254 lemma less_lemma: "\<And> x y. rec_exec rec_less [x, y] = |
|
255 (if x < y then 1 else 0)" |
|
256 by(induct_tac y, auto simp: rec_exec.simps |
|
257 rec_less_def minus_lemma sg_lemma) |
|
258 |
|
259 text {* |
|
260 Correctness of @{text "rec_not"}. |
|
261 *} |
|
262 lemma not_lemma: |
|
263 "\<And> x. rec_exec rec_not [x] = (if x = 0 then 1 else 0)" |
|
264 by(induct_tac x, auto simp: rec_exec.simps rec_not_def |
|
265 constn_lemma minus_lemma) |
|
266 |
|
267 text {* |
|
268 Correctness of @{text "rec_eq"}. |
|
269 *} |
|
270 lemma eq_lemma: "\<And> x y. rec_exec rec_eq [x, y] = (if x = y then 1 else 0)" |
|
271 by(induct_tac y, auto simp: rec_exec.simps rec_eq_def constn_lemma add_lemma minus_lemma) |
|
272 |
|
273 text {* |
|
274 Correctness of @{text "rec_conj"}. |
|
275 *} |
|
276 lemma conj_lemma: "\<And> x y. rec_exec rec_conj [x, y] = (if x = 0 \<or> y = 0 then 0 |
|
277 else 1)" |
|
278 by(induct_tac y, auto simp: rec_exec.simps sg_lemma rec_conj_def mult_lemma) |
|
279 |
|
280 |
|
281 text {* |
|
282 Correctness of @{text "rec_disj"}. |
|
283 *} |
|
284 lemma disj_lemma: "\<And> x y. rec_exec rec_disj [x, y] = (if x = 0 \<and> y = 0 then 0 |
|
285 else 1)" |
|
286 by(induct_tac y, auto simp: rec_disj_def sg_lemma add_lemma rec_exec.simps) |
|
287 |
|
288 |
|
289 text {* |
|
290 @{text "primrec recf n"} is true iff |
|
291 @{text "recf"} is a primitive recursive function |
|
292 with arity @{text "n"}. |
|
293 *} |
|
294 inductive primerec :: "recf \<Rightarrow> nat \<Rightarrow> bool" |
|
295 where |
|
296 prime_z[intro]: "primerec z (Suc 0)" | |
|
297 prime_s[intro]: "primerec s (Suc 0)" | |
|
298 prime_id[intro!]: "\<lbrakk>n < m\<rbrakk> \<Longrightarrow> primerec (id m n) m" | |
|
299 prime_cn[intro!]: "\<lbrakk>primerec f k; length gs = k; |
|
300 \<forall> i < length gs. primerec (gs ! i) m; m = n\<rbrakk> |
|
301 \<Longrightarrow> primerec (Cn n f gs) m" | |
|
302 prime_pr[intro!]: "\<lbrakk>primerec f n; |
|
303 primerec g (Suc (Suc n)); m = Suc n\<rbrakk> |
|
304 \<Longrightarrow> primerec (Pr n f g) m" |
|
305 |
|
306 inductive_cases prime_cn_reverse'[elim]: "primerec (Cn n f gs) n" |
|
307 inductive_cases prime_mn_reverse: "primerec (Mn n f) m" |
|
308 inductive_cases prime_z_reverse[elim]: "primerec z n" |
|
309 inductive_cases prime_s_reverse[elim]: "primerec s n" |
|
310 inductive_cases prime_id_reverse[elim]: "primerec (id m n) k" |
|
311 inductive_cases prime_cn_reverse[elim]: "primerec (Cn n f gs) m" |
|
312 inductive_cases prime_pr_reverse[elim]: "primerec (Pr n f g) m" |
|
313 |
|
314 declare mult_lemma[simp] add_lemma[simp] pred_lemma[simp] |
|
315 minus_lemma[simp] sg_lemma[simp] constn_lemma[simp] |
|
316 less_lemma[simp] not_lemma[simp] eq_lemma[simp] |
|
317 conj_lemma[simp] disj_lemma[simp] |
|
318 |
|
319 text {* |
|
320 @{text "Sigma"} is the logical specification of |
|
321 the recursive function @{text "rec_sigma"}. |
|
322 *} |
|
323 function Sigma :: "(nat list \<Rightarrow> nat) \<Rightarrow> nat list \<Rightarrow> nat" |
|
324 where |
|
325 "Sigma g xs = (if last xs = 0 then g xs |
|
326 else (Sigma g (butlast xs @ [last xs - 1]) + |
|
327 g xs)) " |
|
328 by pat_completeness auto |
|
329 termination |
|
330 proof |
|
331 show "wf (measure (\<lambda> (f, xs). last xs))" by auto |
|
332 next |
|
333 fix g xs |
|
334 assume "last (xs::nat list) \<noteq> 0" |
|
335 thus "((g, butlast xs @ [last xs - 1]), g, xs) |
|
336 \<in> measure (\<lambda>(f, xs). last xs)" |
|
337 by auto |
|
338 qed |
|
339 |
|
340 declare rec_exec.simps[simp del] get_fstn_args.simps[simp del] |
|
341 arity.simps[simp del] Sigma.simps[simp del] |
|
342 rec_sigma.simps[simp del] |
|
343 |
|
344 |
|
345 section {* Properties of @{text rec_sigma} *} |
|
346 |
|
347 lemma [simp]: "arity z = 1" |
|
348 by(simp add: arity.simps) |
|
349 |
|
350 lemma rec_pr_0_simp_rewrite: " |
|
351 rec_exec (Pr n f g) (xs @ [0]) = rec_exec f xs" |
|
352 by(simp add: rec_exec.simps) |
|
353 |
|
354 lemma rec_pr_0_simp_rewrite_single_param: " |
|
355 rec_exec (Pr n f g) [0] = rec_exec f []" |
|
356 by(simp add: rec_exec.simps) |
|
357 |
|
358 lemma rec_pr_Suc_simp_rewrite: |
|
359 "rec_exec (Pr n f g) (xs @ [Suc x]) = |
|
360 rec_exec g (xs @ [x] @ |
|
361 [rec_exec (Pr n f g) (xs @ [x])])" |
|
362 by(simp add: rec_exec.simps) |
|
363 |
|
364 lemma rec_pr_Suc_simp_rewrite_single_param: |
|
365 "rec_exec (Pr n f g) ([Suc x]) = |
|
366 rec_exec g ([x] @ [rec_exec (Pr n f g) ([x])])" |
|
367 by(simp add: rec_exec.simps) |
|
368 |
|
369 thm Sigma.simps |
|
370 |
|
371 lemma Sigma_0_simp_rewrite_single_param: |
|
372 "Sigma f [0] = f [0]" |
|
373 by(simp add: Sigma.simps) |
|
374 |
|
375 lemma Sigma_0_simp_rewrite: |
|
376 "Sigma f (xs @ [0]) = f (xs @ [0])" |
|
377 by(simp add: Sigma.simps) |
|
378 |
|
379 lemma Sigma_Suc_simp_rewrite: |
|
380 "Sigma f (xs @ [Suc x]) = Sigma f (xs @ [x]) + f (xs @ [Suc x])" |
|
381 by(simp add: Sigma.simps) |
|
382 |
|
383 lemma Sigma_Suc_simp_rewrite_single: |
|
384 "Sigma f ([Suc x]) = Sigma f ([x]) + f ([Suc x])" |
|
385 by(simp add: Sigma.simps) |
|
386 |
|
387 lemma [simp]: "(xs @ ys) ! (Suc (length xs)) = ys ! 1" |
|
388 by(simp add: nth_append) |
|
389 |
|
390 lemma get_fstn_args_take: "\<lbrakk>length xs = m; n \<le> m\<rbrakk> \<Longrightarrow> |
|
391 map (\<lambda> f. rec_exec f xs) (get_fstn_args m n)= take n xs" |
|
392 proof(induct n) |
|
393 case 0 thus "?case" |
|
394 by(simp add: get_fstn_args.simps) |
|
395 next |
|
396 case (Suc n) thus "?case" |
|
397 by(simp add: get_fstn_args.simps rec_exec.simps |
|
398 take_Suc_conv_app_nth) |
|
399 qed |
|
400 |
|
401 lemma [simp]: "primerec f n \<Longrightarrow> arity f = n" |
|
402 apply(case_tac f) |
|
403 apply(auto simp: arity.simps ) |
|
404 apply(erule_tac prime_mn_reverse) |
|
405 done |
|
406 |
|
407 lemma rec_sigma_Suc_simp_rewrite: |
|
408 "primerec f (Suc (length xs)) |
|
409 \<Longrightarrow> rec_exec (rec_sigma f) (xs @ [Suc x]) = |
|
410 rec_exec (rec_sigma f) (xs @ [x]) + rec_exec f (xs @ [Suc x])" |
|
411 apply(induct x) |
|
412 apply(auto simp: rec_sigma.simps Let_def rec_pr_Suc_simp_rewrite |
|
413 rec_exec.simps get_fstn_args_take) |
|
414 done |
|
415 |
|
416 text {* |
|
417 The correctness of @{text "rec_sigma"} with respect to its specification. |
|
418 *} |
|
419 lemma sigma_lemma: |
|
420 "primerec rg (Suc (length xs)) |
|
421 \<Longrightarrow> rec_exec (rec_sigma rg) (xs @ [x]) = Sigma (rec_exec rg) (xs @ [x])" |
|
422 apply(induct x) |
|
423 apply(auto simp: rec_exec.simps rec_sigma.simps Let_def |
|
424 get_fstn_args_take Sigma_0_simp_rewrite |
|
425 Sigma_Suc_simp_rewrite) |
|
426 done |
|
427 |
|
428 text {* |
|
429 @{text "rec_accum f (x1, x2, \<dots>, xn, k) = |
|
430 f(x1, x2, \<dots>, xn, 0) * |
|
431 f(x1, x2, \<dots>, xn, 1) * |
|
432 \<dots> |
|
433 f(x1, x2, \<dots>, xn, k)"} |
|
434 *} |
|
435 fun rec_accum :: "recf \<Rightarrow> recf" |
|
436 where |
|
437 "rec_accum rf = |
|
438 (let vl = arity rf in |
|
439 Pr (vl - 1) (Cn (vl - 1) rf (get_fstn_args (vl - 1) (vl - 1) @ |
|
440 [Cn (vl - 1) (constn 0) [id (vl - 1) 0]])) |
|
441 (Cn (Suc vl) rec_mult [id (Suc vl) (vl), |
|
442 Cn (Suc vl) rf (get_fstn_args (Suc vl) (vl - 1) |
|
443 @ [Cn (Suc vl) s [id (Suc vl) (vl - 1)]])]))" |
|
444 |
|
445 text {* |
|
446 @{text "Accum"} is the formal specification of @{text "rec_accum"}. |
|
447 *} |
|
448 function Accum :: "(nat list \<Rightarrow> nat) \<Rightarrow> nat list \<Rightarrow> nat" |
|
449 where |
|
450 "Accum f xs = (if last xs = 0 then f xs |
|
451 else (Accum f (butlast xs @ [last xs - 1]) * |
|
452 f xs))" |
|
453 by pat_completeness auto |
|
454 termination |
|
455 proof |
|
456 show "wf (measure (\<lambda> (f, xs). last xs))" |
|
457 by auto |
|
458 next |
|
459 fix f xs |
|
460 assume "last xs \<noteq> (0::nat)" |
|
461 thus "((f, butlast xs @ [last xs - 1]), f, xs) \<in> |
|
462 measure (\<lambda>(f, xs). last xs)" |
|
463 by auto |
|
464 qed |
|
465 |
|
466 lemma rec_accum_Suc_simp_rewrite: |
|
467 "primerec f (Suc (length xs)) |
|
468 \<Longrightarrow> rec_exec (rec_accum f) (xs @ [Suc x]) = |
|
469 rec_exec (rec_accum f) (xs @ [x]) * rec_exec f (xs @ [Suc x])" |
|
470 apply(induct x) |
|
471 apply(auto simp: rec_sigma.simps Let_def rec_pr_Suc_simp_rewrite |
|
472 rec_exec.simps get_fstn_args_take) |
|
473 done |
|
474 |
|
475 text {* |
|
476 The correctness of @{text "rec_accum"} with respect to its specification. |
|
477 *} |
|
478 lemma accum_lemma : |
|
479 "primerec rg (Suc (length xs)) |
|
480 \<Longrightarrow> rec_exec (rec_accum rg) (xs @ [x]) = Accum (rec_exec rg) (xs @ [x])" |
|
481 apply(induct x) |
|
482 apply(auto simp: rec_exec.simps rec_sigma.simps Let_def |
|
483 get_fstn_args_take) |
|
484 done |
|
485 |
|
486 declare rec_accum.simps [simp del] |
|
487 |
|
488 text {* |
|
489 @{text "rec_all t f (x1, x2, \<dots>, xn)"} |
|
490 computes the charactrization function of the following FOL formula: |
|
491 @{text "(\<forall> x \<le> t(x1, x2, \<dots>, xn). (f(x1, x2, \<dots>, xn, x) > 0))"} |
|
492 *} |
|
493 fun rec_all :: "recf \<Rightarrow> recf \<Rightarrow> recf" |
|
494 where |
|
495 "rec_all rt rf = |
|
496 (let vl = arity rf in |
|
497 Cn (vl - 1) rec_sg [Cn (vl - 1) (rec_accum rf) |
|
498 (get_fstn_args (vl - 1) (vl - 1) @ [rt])])" |
|
499 |
|
500 lemma rec_accum_ex: "primerec rf (Suc (length xs)) \<Longrightarrow> |
|
501 (rec_exec (rec_accum rf) (xs @ [x]) = 0) = |
|
502 (\<exists> t \<le> x. rec_exec rf (xs @ [t]) = 0)" |
|
503 apply(induct x, simp_all add: rec_accum_Suc_simp_rewrite) |
|
504 apply(simp add: rec_exec.simps rec_accum.simps get_fstn_args_take, |
|
505 auto) |
|
506 apply(rule_tac x = ta in exI, simp) |
|
507 apply(case_tac "t = Suc x", simp_all) |
|
508 apply(rule_tac x = t in exI, simp) |
|
509 done |
|
510 |
|
511 text {* |
|
512 The correctness of @{text "rec_all"}. |
|
513 *} |
|
514 lemma all_lemma: |
|
515 "\<lbrakk>primerec rf (Suc (length xs)); |
|
516 primerec rt (length xs)\<rbrakk> |
|
517 \<Longrightarrow> rec_exec (rec_all rt rf) xs = (if (\<forall> x \<le> (rec_exec rt xs). 0 < rec_exec rf (xs @ [x])) then 1 |
|
518 else 0)" |
|
519 apply(auto simp: rec_all.simps) |
|
520 apply(simp add: rec_exec.simps map_append get_fstn_args_take split: if_splits) |
|
521 apply(drule_tac x = "rec_exec rt xs" in rec_accum_ex) |
|
522 apply(case_tac "rec_exec (rec_accum rf) (xs @ [rec_exec rt xs]) = 0", simp_all) |
|
523 apply(erule_tac exE, erule_tac x = t in allE, simp) |
|
524 apply(simp add: rec_exec.simps map_append get_fstn_args_take) |
|
525 apply(drule_tac x = "rec_exec rt xs" in rec_accum_ex) |
|
526 apply(case_tac "rec_exec (rec_accum rf) (xs @ [rec_exec rt xs]) = 0", simp, simp) |
|
527 apply(erule_tac x = x in allE, simp) |
|
528 done |
|
529 |
|
530 text {* |
|
531 @{text "rec_ex t f (x1, x2, \<dots>, xn)"} |
|
532 computes the charactrization function of the following FOL formula: |
|
533 @{text "(\<exists> x \<le> t(x1, x2, \<dots>, xn). (f(x1, x2, \<dots>, xn, x) > 0))"} |
|
534 *} |
|
535 fun rec_ex :: "recf \<Rightarrow> recf \<Rightarrow> recf" |
|
536 where |
|
537 "rec_ex rt rf = |
|
538 (let vl = arity rf in |
|
539 Cn (vl - 1) rec_sg [Cn (vl - 1) (rec_sigma rf) |
|
540 (get_fstn_args (vl - 1) (vl - 1) @ [rt])])" |
|
541 |
|
542 lemma rec_sigma_ex: "primerec rf (Suc (length xs)) |
|
543 \<Longrightarrow> (rec_exec (rec_sigma rf) (xs @ [x]) = 0) = |
|
544 (\<forall> t \<le> x. rec_exec rf (xs @ [t]) = 0)" |
|
545 apply(induct x, simp_all add: rec_sigma_Suc_simp_rewrite) |
|
546 apply(simp add: rec_exec.simps rec_sigma.simps |
|
547 get_fstn_args_take, auto) |
|
548 apply(case_tac "t = Suc x", simp_all) |
|
549 done |
|
550 |
|
551 text {* |
|
552 The correctness of @{text "ex_lemma"}. |
|
553 *} |
|
554 lemma ex_lemma:" |
|
555 \<lbrakk>primerec rf (Suc (length xs)); |
|
556 primerec rt (length xs)\<rbrakk> |
|
557 \<Longrightarrow> (rec_exec (rec_ex rt rf) xs = |
|
558 (if (\<exists> x \<le> (rec_exec rt xs). 0 <rec_exec rf (xs @ [x])) then 1 |
|
559 else 0))" |
|
560 apply(auto simp: rec_ex.simps rec_exec.simps map_append get_fstn_args_take |
|
561 split: if_splits) |
|
562 apply(drule_tac x = "rec_exec rt xs" in rec_sigma_ex, simp) |
|
563 apply(drule_tac x = "rec_exec rt xs" in rec_sigma_ex, simp) |
|
564 done |
|
565 |
|
566 text {* |
|
567 Defintiion of @{text "Min[R]"} on page 77 of Boolos's book. |
|
568 *} |
|
569 |
|
570 fun Minr :: "(nat list \<Rightarrow> bool) \<Rightarrow> nat list \<Rightarrow> nat \<Rightarrow> nat" |
|
571 where "Minr Rr xs w = (let setx = {y | y. (y \<le> w) \<and> Rr (xs @ [y])} in |
|
572 if (setx = {}) then (Suc w) |
|
573 else (Min setx))" |
|
574 |
|
575 declare Minr.simps[simp del] rec_all.simps[simp del] |
|
576 |
|
577 text {* |
|
578 The following is a set of auxilliary lemmas about @{text "Minr"}. |
|
579 *} |
|
580 lemma Minr_range: "Minr Rr xs w \<le> w \<or> Minr Rr xs w = Suc w" |
|
581 apply(auto simp: Minr.simps) |
|
582 apply(subgoal_tac "Min {x. x \<le> w \<and> Rr (xs @ [x])} \<le> x") |
|
583 apply(erule_tac order_trans, simp) |
|
584 apply(rule_tac Min_le, auto) |
|
585 done |
|
586 |
|
587 lemma [simp]: "{x. x \<le> Suc w \<and> Rr (xs @ [x])} |
|
588 = (if Rr (xs @ [Suc w]) then insert (Suc w) |
|
589 {x. x \<le> w \<and> Rr (xs @ [x])} |
|
590 else {x. x \<le> w \<and> Rr (xs @ [x])})" |
|
591 by(auto, case_tac "x = Suc w", auto) |
|
592 |
|
593 lemma [simp]: "Minr Rr xs w \<le> w \<Longrightarrow> Minr Rr xs (Suc w) = Minr Rr xs w" |
|
594 apply(simp add: Minr.simps, auto) |
|
595 apply(case_tac "\<forall>x\<le>w. \<not> Rr (xs @ [x])", auto) |
|
596 done |
|
597 |
|
598 lemma [simp]: "\<forall>x\<le>w. \<not> Rr (xs @ [x]) \<Longrightarrow> |
|
599 {x. x \<le> w \<and> Rr (xs @ [x])} = {} " |
|
600 by auto |
|
601 |
|
602 lemma [simp]: "\<lbrakk>Minr Rr xs w = Suc w; Rr (xs @ [Suc w])\<rbrakk> \<Longrightarrow> |
|
603 Minr Rr xs (Suc w) = Suc w" |
|
604 apply(simp add: Minr.simps) |
|
605 apply(case_tac "\<forall>x\<le>w. \<not> Rr (xs @ [x])", auto) |
|
606 done |
|
607 |
|
608 lemma [simp]: "\<lbrakk>Minr Rr xs w = Suc w; \<not> Rr (xs @ [Suc w])\<rbrakk> \<Longrightarrow> |
|
609 Minr Rr xs (Suc w) = Suc (Suc w)" |
|
610 apply(simp add: Minr.simps) |
|
611 apply(case_tac "\<forall>x\<le>w. \<not> Rr (xs @ [x])", auto) |
|
612 apply(subgoal_tac "Min {x. x \<le> w \<and> Rr (xs @ [x])} \<in> |
|
613 {x. x \<le> w \<and> Rr (xs @ [x])}", simp) |
|
614 apply(rule_tac Min_in, auto) |
|
615 done |
|
616 |
|
617 lemma Minr_Suc_simp: |
|
618 "Minr Rr xs (Suc w) = |
|
619 (if Minr Rr xs w \<le> w then Minr Rr xs w |
|
620 else if (Rr (xs @ [Suc w])) then (Suc w) |
|
621 else Suc (Suc w))" |
|
622 by(insert Minr_range[of Rr xs w], auto) |
|
623 |
|
624 text {* |
|
625 @{text "rec_Minr"} is the recursive function |
|
626 used to implement @{text "Minr"}: |
|
627 if @{text "Rr"} is implemented by a recursive function @{text "recf"}, |
|
628 then @{text "rec_Minr recf"} is the recursive function used to |
|
629 implement @{text "Minr Rr"} |
|
630 *} |
|
631 fun rec_Minr :: "recf \<Rightarrow> recf" |
|
632 where |
|
633 "rec_Minr rf = |
|
634 (let vl = arity rf |
|
635 in let rq = rec_all (id vl (vl - 1)) (Cn (Suc vl) |
|
636 rec_not [Cn (Suc vl) rf |
|
637 (get_fstn_args (Suc vl) (vl - 1) @ |
|
638 [id (Suc vl) (vl)])]) |
|
639 in rec_sigma rq)" |
|
640 |
|
641 lemma length_getpren_params[simp]: "length (get_fstn_args m n) = n" |
|
642 by(induct n, auto simp: get_fstn_args.simps) |
|
643 |
|
644 lemma length_app: |
|
645 "(length (get_fstn_args (arity rf - Suc 0) |
|
646 (arity rf - Suc 0) |
|
647 @ [Cn (arity rf - Suc 0) (constn 0) |
|
648 [recf.id (arity rf - Suc 0) 0]])) |
|
649 = (Suc (arity rf - Suc 0))" |
|
650 apply(simp) |
|
651 done |
|
652 |
|
653 lemma primerec_accum: "primerec (rec_accum rf) n \<Longrightarrow> primerec rf n" |
|
654 apply(auto simp: rec_accum.simps Let_def) |
|
655 apply(erule_tac prime_pr_reverse, simp) |
|
656 apply(erule_tac prime_cn_reverse, simp only: length_app) |
|
657 done |
|
658 |
|
659 lemma primerec_all: "primerec (rec_all rt rf) n \<Longrightarrow> |
|
660 primerec rt n \<and> primerec rf (Suc n)" |
|
661 apply(simp add: rec_all.simps Let_def) |
|
662 apply(erule_tac prime_cn_reverse, simp) |
|
663 apply(erule_tac prime_cn_reverse, simp) |
|
664 apply(erule_tac x = n in allE, simp add: nth_append primerec_accum) |
|
665 done |
|
666 |
|
667 lemma min_Suc_Suc[simp]: "min (Suc (Suc x)) x = x" |
|
668 by auto |
|
669 |
|
670 declare numeral_3_eq_3[simp] |
|
671 |
|
672 lemma [intro]: "primerec rec_pred (Suc 0)" |
|
673 apply(simp add: rec_pred_def) |
|
674 apply(rule_tac prime_cn, auto) |
|
675 apply(case_tac i, auto intro: prime_id) |
|
676 done |
|
677 |
|
678 lemma [intro]: "primerec rec_minus (Suc (Suc 0))" |
|
679 apply(auto simp: rec_minus_def) |
|
680 done |
|
681 |
|
682 lemma [intro]: "primerec (constn n) (Suc 0)" |
|
683 apply(induct n) |
|
684 apply(auto simp: constn.simps intro: prime_z prime_cn prime_s) |
|
685 done |
|
686 |
|
687 lemma [intro]: "primerec rec_sg (Suc 0)" |
|
688 apply(simp add: rec_sg_def) |
|
689 apply(rule_tac k = "Suc (Suc 0)" in prime_cn, auto) |
|
690 apply(case_tac i, auto) |
|
691 apply(case_tac ia, auto intro: prime_id) |
|
692 done |
|
693 |
|
694 lemma [simp]: "length (get_fstn_args m n) = n" |
|
695 apply(induct n) |
|
696 apply(auto simp: get_fstn_args.simps) |
|
697 done |
|
698 |
|
699 lemma primerec_getpren[elim]: "\<lbrakk>i < n; n \<le> m\<rbrakk> \<Longrightarrow> primerec (get_fstn_args m n ! i) m" |
|
700 apply(induct n, auto simp: get_fstn_args.simps) |
|
701 apply(case_tac "i = n", auto simp: nth_append intro: prime_id) |
|
702 done |
|
703 |
|
704 lemma [intro]: "primerec rec_add (Suc (Suc 0))" |
|
705 apply(simp add: rec_add_def) |
|
706 apply(rule_tac prime_pr, auto) |
|
707 done |
|
708 |
|
709 lemma [intro]:"primerec rec_mult (Suc (Suc 0))" |
|
710 apply(simp add: rec_mult_def ) |
|
711 apply(rule_tac prime_pr, auto intro: prime_z) |
|
712 apply(case_tac i, auto intro: prime_id) |
|
713 done |
|
714 |
|
715 lemma [elim]: "\<lbrakk>primerec rf n; n \<ge> Suc (Suc 0)\<rbrakk> \<Longrightarrow> |
|
716 primerec (rec_accum rf) n" |
|
717 apply(auto simp: rec_accum.simps) |
|
718 apply(simp add: nth_append, auto) |
|
719 apply(case_tac i, auto intro: prime_id) |
|
720 apply(auto simp: nth_append) |
|
721 done |
|
722 |
|
723 lemma primerec_all_iff: |
|
724 "\<lbrakk>primerec rt n; primerec rf (Suc n); n > 0\<rbrakk> \<Longrightarrow> |
|
725 primerec (rec_all rt rf) n" |
|
726 apply(simp add: rec_all.simps, auto) |
|
727 apply(auto, simp add: nth_append, auto) |
|
728 done |
|
729 |
|
730 lemma [simp]: "Rr (xs @ [0]) \<Longrightarrow> |
|
731 Min {x. x = (0::nat) \<and> Rr (xs @ [x])} = 0" |
|
732 by(rule_tac Min_eqI, simp, simp, simp) |
|
733 |
|
734 lemma [intro]: "primerec rec_not (Suc 0)" |
|
735 apply(simp add: rec_not_def) |
|
736 apply(rule prime_cn, auto) |
|
737 apply(case_tac i, auto intro: prime_id) |
|
738 done |
|
739 |
|
740 lemma Min_false1[simp]: "\<lbrakk>\<not> Min {uu. uu \<le> w \<and> 0 < rec_exec rf (xs @ [uu])} \<le> w; |
|
741 x \<le> w; 0 < rec_exec rf (xs @ [x])\<rbrakk> |
|
742 \<Longrightarrow> False" |
|
743 apply(subgoal_tac "finite {uu. uu \<le> w \<and> 0 < rec_exec rf (xs @ [uu])}") |
|
744 apply(subgoal_tac "{uu. uu \<le> w \<and> 0 < rec_exec rf (xs @ [uu])} \<noteq> {}") |
|
745 apply(simp add: Min_le_iff, simp) |
|
746 apply(rule_tac x = x in exI, simp) |
|
747 apply(simp) |
|
748 done |
|
749 |
|
750 lemma sigma_minr_lemma: |
|
751 assumes prrf: "primerec rf (Suc (length xs))" |
|
752 shows "UF.Sigma (rec_exec (rec_all (recf.id (Suc (length xs)) (length xs)) |
|
753 (Cn (Suc (Suc (length xs))) rec_not |
|
754 [Cn (Suc (Suc (length xs))) rf (get_fstn_args (Suc (Suc (length xs))) |
|
755 (length xs) @ [recf.id (Suc (Suc (length xs))) (Suc (length xs))])]))) |
|
756 (xs @ [w]) = |
|
757 Minr (\<lambda>args. 0 < rec_exec rf args) xs w" |
|
758 proof(induct w) |
|
759 let ?rt = "(recf.id (Suc (length xs)) ((length xs)))" |
|
760 let ?rf = "(Cn (Suc (Suc (length xs))) |
|
761 rec_not [Cn (Suc (Suc (length xs))) rf |
|
762 (get_fstn_args (Suc (Suc (length xs))) (length xs) @ |
|
763 [recf.id (Suc (Suc (length xs))) |
|
764 (Suc ((length xs)))])])" |
|
765 let ?rq = "(rec_all ?rt ?rf)" |
|
766 have prrf: "primerec ?rf (Suc (length (xs @ [0]))) \<and> |
|
767 primerec ?rt (length (xs @ [0]))" |
|
768 apply(auto simp: prrf nth_append)+ |
|
769 done |
|
770 show "Sigma (rec_exec (rec_all ?rt ?rf)) (xs @ [0]) |
|
771 = Minr (\<lambda>args. 0 < rec_exec rf args) xs 0" |
|
772 apply(simp add: Sigma.simps) |
|
773 apply(simp only: prrf all_lemma, |
|
774 auto simp: rec_exec.simps get_fstn_args_take Minr.simps) |
|
775 apply(rule_tac Min_eqI, auto) |
|
776 done |
|
777 next |
|
778 fix w |
|
779 let ?rt = "(recf.id (Suc (length xs)) ((length xs)))" |
|
780 let ?rf = "(Cn (Suc (Suc (length xs))) |
|
781 rec_not [Cn (Suc (Suc (length xs))) rf |
|
782 (get_fstn_args (Suc (Suc (length xs))) (length xs) @ |
|
783 [recf.id (Suc (Suc (length xs))) |
|
784 (Suc ((length xs)))])])" |
|
785 let ?rq = "(rec_all ?rt ?rf)" |
|
786 assume ind: |
|
787 "Sigma (rec_exec (rec_all ?rt ?rf)) (xs @ [w]) = Minr (\<lambda>args. 0 < rec_exec rf args) xs w" |
|
788 have prrf: "primerec ?rf (Suc (length (xs @ [Suc w]))) \<and> |
|
789 primerec ?rt (length (xs @ [Suc w]))" |
|
790 apply(auto simp: prrf nth_append)+ |
|
791 done |
|
792 show "UF.Sigma (rec_exec (rec_all ?rt ?rf)) |
|
793 (xs @ [Suc w]) = |
|
794 Minr (\<lambda>args. 0 < rec_exec rf args) xs (Suc w)" |
|
795 apply(auto simp: Sigma_Suc_simp_rewrite ind Minr_Suc_simp) |
|
796 apply(simp_all only: prrf all_lemma) |
|
797 apply(auto simp: rec_exec.simps get_fstn_args_take Let_def Minr.simps split: if_splits) |
|
798 apply(drule_tac Min_false1, simp, simp, simp) |
|
799 apply(case_tac "x = Suc w", simp, simp) |
|
800 apply(drule_tac Min_false1, simp, simp, simp) |
|
801 apply(drule_tac Min_false1, simp, simp, simp) |
|
802 done |
|
803 qed |
|
804 |
|
805 text {* |
|
806 The correctness of @{text "rec_Minr"}. |
|
807 *} |
|
808 lemma Minr_lemma: " |
|
809 \<lbrakk>primerec rf (Suc (length xs))\<rbrakk> |
|
810 \<Longrightarrow> rec_exec (rec_Minr rf) (xs @ [w]) = |
|
811 Minr (\<lambda> args. (0 < rec_exec rf args)) xs w" |
|
812 proof - |
|
813 let ?rt = "(recf.id (Suc (length xs)) ((length xs)))" |
|
814 let ?rf = "(Cn (Suc (Suc (length xs))) |
|
815 rec_not [Cn (Suc (Suc (length xs))) rf |
|
816 (get_fstn_args (Suc (Suc (length xs))) (length xs) @ |
|
817 [recf.id (Suc (Suc (length xs))) |
|
818 (Suc ((length xs)))])])" |
|
819 let ?rq = "(rec_all ?rt ?rf)" |
|
820 assume h: "primerec rf (Suc (length xs))" |
|
821 have h1: "primerec ?rq (Suc (length xs))" |
|
822 apply(rule_tac primerec_all_iff) |
|
823 apply(auto simp: h nth_append)+ |
|
824 done |
|
825 moreover have "arity rf = Suc (length xs)" |
|
826 using h by auto |
|
827 ultimately show "rec_exec (rec_Minr rf) (xs @ [w]) = |
|
828 Minr (\<lambda> args. (0 < rec_exec rf args)) xs w" |
|
829 apply(simp add: rec_exec.simps rec_Minr.simps arity.simps Let_def |
|
830 sigma_lemma all_lemma) |
|
831 apply(rule_tac sigma_minr_lemma) |
|
832 apply(simp add: h) |
|
833 done |
|
834 qed |
|
835 |
|
836 text {* |
|
837 @{text "rec_le"} is the comparasion function |
|
838 which compares its two arguments, testing whether the |
|
839 first is less or equal to the second. |
|
840 *} |
|
841 definition rec_le :: "recf" |
|
842 where |
|
843 "rec_le = Cn (Suc (Suc 0)) rec_disj [rec_less, rec_eq]" |
|
844 |
|
845 text {* |
|
846 The correctness of @{text "rec_le"}. |
|
847 *} |
|
848 lemma le_lemma: |
|
849 "\<And>x y. rec_exec rec_le [x, y] = (if (x \<le> y) then 1 else 0)" |
|
850 by(auto simp: rec_le_def rec_exec.simps) |
|
851 |
|
852 text {* |
|
853 Defintiion of @{text "Max[Rr]"} on page 77 of Boolos's book. |
|
854 *} |
|
855 |
|
856 fun Maxr :: "(nat list \<Rightarrow> bool) \<Rightarrow> nat list \<Rightarrow> nat \<Rightarrow> nat" |
|
857 where |
|
858 "Maxr Rr xs w = (let setx = {y. y \<le> w \<and> Rr (xs @[y])} in |
|
859 if setx = {} then 0 |
|
860 else Max setx)" |
|
861 |
|
862 text {* |
|
863 @{text "rec_maxr"} is the recursive function |
|
864 used to implementation @{text "Maxr"}. |
|
865 *} |
|
866 fun rec_maxr :: "recf \<Rightarrow> recf" |
|
867 where |
|
868 "rec_maxr rr = (let vl = arity rr in |
|
869 let rt = id (Suc vl) (vl - 1) in |
|
870 let rf1 = Cn (Suc (Suc vl)) rec_le |
|
871 [id (Suc (Suc vl)) |
|
872 ((Suc vl)), id (Suc (Suc vl)) (vl)] in |
|
873 let rf2 = Cn (Suc (Suc vl)) rec_not |
|
874 [Cn (Suc (Suc vl)) |
|
875 rr (get_fstn_args (Suc (Suc vl)) |
|
876 (vl - 1) @ |
|
877 [id (Suc (Suc vl)) ((Suc vl))])] in |
|
878 let rf = Cn (Suc (Suc vl)) rec_disj [rf1, rf2] in |
|
879 let rq = rec_all rt rf in |
|
880 let Qf = Cn (Suc vl) rec_not [rec_all rt rf] |
|
881 in Cn vl (rec_sigma Qf) (get_fstn_args vl vl @ |
|
882 [id vl (vl - 1)]))" |
|
883 |
|
884 declare rec_maxr.simps[simp del] Maxr.simps[simp del] |
|
885 declare le_lemma[simp] |
|
886 lemma [simp]: "(min (Suc (Suc (Suc (x)))) (x)) = x" |
|
887 by simp |
|
888 |
|
889 declare numeral_2_eq_2[simp] |
|
890 |
|
891 lemma [intro]: "primerec rec_disj (Suc (Suc 0))" |
|
892 apply(simp add: rec_disj_def, auto) |
|
893 apply(auto) |
|
894 apply(case_tac ia, auto intro: prime_id) |
|
895 done |
|
896 |
|
897 lemma [intro]: "primerec rec_less (Suc (Suc 0))" |
|
898 apply(simp add: rec_less_def, auto) |
|
899 apply(auto) |
|
900 apply(case_tac ia , auto intro: prime_id) |
|
901 done |
|
902 |
|
903 lemma [intro]: "primerec rec_eq (Suc (Suc 0))" |
|
904 apply(simp add: rec_eq_def) |
|
905 apply(rule_tac prime_cn, auto) |
|
906 apply(case_tac i, auto) |
|
907 apply(case_tac ia, auto) |
|
908 apply(case_tac [!] i, auto intro: prime_id) |
|
909 done |
|
910 |
|
911 lemma [intro]: "primerec rec_le (Suc (Suc 0))" |
|
912 apply(simp add: rec_le_def) |
|
913 apply(rule_tac prime_cn, auto) |
|
914 apply(case_tac i, auto) |
|
915 done |
|
916 |
|
917 lemma [simp]: |
|
918 "length ys = Suc n \<Longrightarrow> (take n ys @ [ys ! n, ys ! n]) = |
|
919 ys @ [ys ! n]" |
|
920 apply(simp) |
|
921 apply(subgoal_tac "\<exists> xs y. ys = xs @ [y]", auto) |
|
922 apply(rule_tac x = "butlast ys" in exI, rule_tac x = "last ys" in exI) |
|
923 apply(case_tac "ys = []", simp_all) |
|
924 done |
|
925 |
|
926 lemma Maxr_Suc_simp: |
|
927 "Maxr Rr xs (Suc w) =(if Rr (xs @ [Suc w]) then Suc w |
|
928 else Maxr Rr xs w)" |
|
929 apply(auto simp: Maxr.simps) |
|
930 apply(rule_tac max_absorb1) |
|
931 apply(subgoal_tac "(Max {y. y \<le> w \<and> Rr (xs @ [y])} \<le> (Suc w)) = |
|
932 (\<forall>a\<in>{y. y \<le> w \<and> Rr (xs @ [y])}. a \<le> (Suc w))", simp) |
|
933 apply(rule_tac Max_le_iff, auto) |
|
934 done |
|
935 |
|
936 |
|
937 lemma [simp]: "min (Suc n) n = n" by simp |
|
938 |
|
939 lemma Sigma_0: "\<forall> i \<le> n. (f (xs @ [i]) = 0) \<Longrightarrow> |
|
940 Sigma f (xs @ [n]) = 0" |
|
941 apply(induct n, simp add: Sigma.simps) |
|
942 apply(simp add: Sigma_Suc_simp_rewrite) |
|
943 done |
|
944 |
|
945 lemma [elim]: "\<forall>k<Suc w. f (xs @ [k]) = Suc 0 |
|
946 \<Longrightarrow> Sigma f (xs @ [w]) = Suc w" |
|
947 apply(induct w) |
|
948 apply(simp add: Sigma.simps, simp) |
|
949 apply(simp add: Sigma.simps) |
|
950 done |
|
951 |
|
952 lemma Sigma_max_point: "\<lbrakk>\<forall> k < ma. f (xs @ [k]) = 1; |
|
953 \<forall> k \<ge> ma. f (xs @ [k]) = 0; ma \<le> w\<rbrakk> |
|
954 \<Longrightarrow> Sigma f (xs @ [w]) = ma" |
|
955 apply(induct w, auto) |
|
956 apply(rule_tac Sigma_0, simp) |
|
957 apply(simp add: Sigma_Suc_simp_rewrite) |
|
958 apply(case_tac "ma = Suc w", auto) |
|
959 done |
|
960 |
|
961 lemma Sigma_Max_lemma: |
|
962 assumes prrf: "primerec rf (Suc (length xs))" |
|
963 shows "UF.Sigma (rec_exec (Cn (Suc (Suc (length xs))) rec_not |
|
964 [rec_all (recf.id (Suc (Suc (length xs))) (length xs)) |
|
965 (Cn (Suc (Suc (Suc (length xs)))) rec_disj |
|
966 [Cn (Suc (Suc (Suc (length xs)))) rec_le |
|
967 [recf.id (Suc (Suc (Suc (length xs)))) (Suc (Suc (length xs))), |
|
968 recf.id (Suc (Suc (Suc (length xs)))) (Suc (length xs))], |
|
969 Cn (Suc (Suc (Suc (length xs)))) rec_not |
|
970 [Cn (Suc (Suc (Suc (length xs)))) rf |
|
971 (get_fstn_args (Suc (Suc (Suc (length xs)))) (length xs) @ |
|
972 [recf.id (Suc (Suc (Suc (length xs)))) (Suc (Suc (length xs)))])]])])) |
|
973 ((xs @ [w]) @ [w]) = |
|
974 Maxr (\<lambda>args. 0 < rec_exec rf args) xs w" |
|
975 proof - |
|
976 let ?rt = "(recf.id (Suc (Suc (length xs))) ((length xs)))" |
|
977 let ?rf1 = "Cn (Suc (Suc (Suc (length xs)))) |
|
978 rec_le [recf.id (Suc (Suc (Suc (length xs)))) |
|
979 ((Suc (Suc (length xs)))), recf.id |
|
980 (Suc (Suc (Suc (length xs)))) ((Suc (length xs)))]" |
|
981 let ?rf2 = "Cn (Suc (Suc (Suc (length xs)))) rf |
|
982 (get_fstn_args (Suc (Suc (Suc (length xs)))) |
|
983 (length xs) @ |
|
984 [recf.id (Suc (Suc (Suc (length xs)))) |
|
985 ((Suc (Suc (length xs))))])" |
|
986 let ?rf3 = "Cn (Suc (Suc (Suc (length xs)))) rec_not [?rf2]" |
|
987 let ?rf = "Cn (Suc (Suc (Suc (length xs)))) rec_disj [?rf1, ?rf3]" |
|
988 let ?rq = "rec_all ?rt ?rf" |
|
989 let ?notrq = "Cn (Suc (Suc (length xs))) rec_not [?rq]" |
|
990 show "?thesis" |
|
991 proof(auto simp: Maxr.simps) |
|
992 assume h: "\<forall>x\<le>w. rec_exec rf (xs @ [x]) = 0" |
|
993 have "primerec ?rf (Suc (length (xs @ [w, i]))) \<and> |
|
994 primerec ?rt (length (xs @ [w, i]))" |
|
995 using prrf |
|
996 apply(auto) |
|
997 apply(case_tac i, auto) |
|
998 apply(case_tac ia, auto simp: h nth_append) |
|
999 done |
|
1000 hence "Sigma (rec_exec ?notrq) ((xs@[w])@[w]) = 0" |
|
1001 apply(rule_tac Sigma_0) |
|
1002 apply(auto simp: rec_exec.simps all_lemma |
|
1003 get_fstn_args_take nth_append h) |
|
1004 done |
|
1005 thus "UF.Sigma (rec_exec ?notrq) |
|
1006 (xs @ [w, w]) = 0" |
|
1007 by simp |
|
1008 next |
|
1009 fix x |
|
1010 assume h: "x \<le> w" "0 < rec_exec rf (xs @ [x])" |
|
1011 hence "\<exists> ma. Max {y. y \<le> w \<and> 0 < rec_exec rf (xs @ [y])} = ma" |
|
1012 by auto |
|
1013 from this obtain ma where k1: |
|
1014 "Max {y. y \<le> w \<and> 0 < rec_exec rf (xs @ [y])} = ma" .. |
|
1015 hence k2: "ma \<le> w \<and> 0 < rec_exec rf (xs @ [ma])" |
|
1016 using h |
|
1017 apply(subgoal_tac |
|
1018 "Max {y. y \<le> w \<and> 0 < rec_exec rf (xs @ [y])} \<in> {y. y \<le> w \<and> 0 < rec_exec rf (xs @ [y])}") |
|
1019 apply(erule_tac CollectE, simp) |
|
1020 apply(rule_tac Max_in, auto) |
|
1021 done |
|
1022 hence k3: "\<forall> k < ma. (rec_exec ?notrq (xs @ [w, k]) = 1)" |
|
1023 apply(auto simp: nth_append) |
|
1024 apply(subgoal_tac "primerec ?rf (Suc (length (xs @ [w, k]))) \<and> |
|
1025 primerec ?rt (length (xs @ [w, k]))") |
|
1026 apply(auto simp: rec_exec.simps all_lemma get_fstn_args_take nth_append) |
|
1027 using prrf |
|
1028 apply(case_tac i, auto) |
|
1029 apply(case_tac ia, auto simp: h nth_append) |
|
1030 done |
|
1031 have k4: "\<forall> k \<ge> ma. (rec_exec ?notrq (xs @ [w, k]) = 0)" |
|
1032 apply(auto) |
|
1033 apply(subgoal_tac "primerec ?rf (Suc (length (xs @ [w, k]))) \<and> |
|
1034 primerec ?rt (length (xs @ [w, k]))") |
|
1035 apply(auto simp: rec_exec.simps all_lemma get_fstn_args_take nth_append) |
|
1036 apply(subgoal_tac "x \<le> Max {y. y \<le> w \<and> 0 < rec_exec rf (xs @ [y])}", |
|
1037 simp add: k1) |
|
1038 apply(rule_tac Max_ge, auto) |
|
1039 using prrf |
|
1040 apply(case_tac i, auto) |
|
1041 apply(case_tac ia, auto simp: h nth_append) |
|
1042 done |
|
1043 from k3 k4 k1 have "Sigma (rec_exec ?notrq) ((xs @ [w]) @ [w]) = ma" |
|
1044 apply(rule_tac Sigma_max_point, simp, simp, simp add: k2) |
|
1045 done |
|
1046 from k1 and this show "Sigma (rec_exec ?notrq) (xs @ [w, w]) = |
|
1047 Max {y. y \<le> w \<and> 0 < rec_exec rf (xs @ [y])}" |
|
1048 by simp |
|
1049 qed |
|
1050 qed |
|
1051 |
|
1052 text {* |
|
1053 The correctness of @{text "rec_maxr"}. |
|
1054 *} |
|
1055 lemma Maxr_lemma: |
|
1056 assumes h: "primerec rf (Suc (length xs))" |
|
1057 shows "rec_exec (rec_maxr rf) (xs @ [w]) = |
|
1058 Maxr (\<lambda> args. 0 < rec_exec rf args) xs w" |
|
1059 proof - |
|
1060 from h have "arity rf = Suc (length xs)" |
|
1061 by auto |
|
1062 thus "?thesis" |
|
1063 proof(simp add: rec_exec.simps rec_maxr.simps nth_append get_fstn_args_take) |
|
1064 let ?rt = "(recf.id (Suc (Suc (length xs))) ((length xs)))" |
|
1065 let ?rf1 = "Cn (Suc (Suc (Suc (length xs)))) |
|
1066 rec_le [recf.id (Suc (Suc (Suc (length xs)))) |
|
1067 ((Suc (Suc (length xs)))), recf.id |
|
1068 (Suc (Suc (Suc (length xs)))) ((Suc (length xs)))]" |
|
1069 let ?rf2 = "Cn (Suc (Suc (Suc (length xs)))) rf |
|
1070 (get_fstn_args (Suc (Suc (Suc (length xs)))) |
|
1071 (length xs) @ |
|
1072 [recf.id (Suc (Suc (Suc (length xs)))) |
|
1073 ((Suc (Suc (length xs))))])" |
|
1074 let ?rf3 = "Cn (Suc (Suc (Suc (length xs)))) rec_not [?rf2]" |
|
1075 let ?rf = "Cn (Suc (Suc (Suc (length xs)))) rec_disj [?rf1, ?rf3]" |
|
1076 let ?rq = "rec_all ?rt ?rf" |
|
1077 let ?notrq = "Cn (Suc (Suc (length xs))) rec_not [?rq]" |
|
1078 have prt: "primerec ?rt (Suc (Suc (length xs)))" |
|
1079 by(auto intro: prime_id) |
|
1080 have prrf: "primerec ?rf (Suc (Suc (Suc (length xs))))" |
|
1081 apply(auto) |
|
1082 apply(case_tac i, auto) |
|
1083 apply(case_tac ia, auto intro: prime_id) |
|
1084 apply(simp add: h) |
|
1085 apply(simp add: nth_append, auto intro: prime_id) |
|
1086 done |
|
1087 from prt and prrf have prrq: "primerec ?rq |
|
1088 (Suc (Suc (length xs)))" |
|
1089 by(erule_tac primerec_all_iff, auto) |
|
1090 hence prnotrp: "primerec ?notrq (Suc (length ((xs @ [w]))))" |
|
1091 by(rule_tac prime_cn, auto) |
|
1092 have g1: "rec_exec (rec_sigma ?notrq) ((xs @ [w]) @ [w]) |
|
1093 = Maxr (\<lambda>args. 0 < rec_exec rf args) xs w" |
|
1094 using prnotrp |
|
1095 using sigma_lemma |
|
1096 apply(simp only: sigma_lemma) |
|
1097 apply(rule_tac Sigma_Max_lemma) |
|
1098 apply(simp add: h) |
|
1099 done |
|
1100 thus "rec_exec (rec_sigma ?notrq) |
|
1101 (xs @ [w, w]) = |
|
1102 Maxr (\<lambda>args. 0 < rec_exec rf args) xs w" |
|
1103 apply(simp) |
|
1104 done |
|
1105 qed |
|
1106 qed |
|
1107 |
|
1108 text {* |
|
1109 @text "quo"} is the formal specification of division. |
|
1110 *} |
|
1111 fun quo :: "nat list \<Rightarrow> nat" |
|
1112 where |
|
1113 "quo [x, y] = (let Rr = |
|
1114 (\<lambda> zs. ((zs ! (Suc 0) * zs ! (Suc (Suc 0)) |
|
1115 \<le> zs ! 0) \<and> zs ! Suc 0 \<noteq> (0::nat))) |
|
1116 in Maxr Rr [x, y] x)" |
|
1117 |
|
1118 declare quo.simps[simp del] |
|
1119 |
|
1120 text {* |
|
1121 The following lemmas shows more directly the menaing of @{text "quo"}: |
|
1122 *} |
|
1123 lemma [elim!]: "y > 0 \<Longrightarrow> quo [x, y] = x div y" |
|
1124 proof(simp add: quo.simps Maxr.simps, auto, |
|
1125 rule_tac Max_eqI, simp, auto) |
|
1126 fix xa ya |
|
1127 assume h: "y * ya \<le> x" "y > 0" |
|
1128 hence "(y * ya) div y \<le> x div y" |
|
1129 by(insert div_le_mono[of "y * ya" x y], simp) |
|
1130 from this and h show "ya \<le> x div y" by simp |
|
1131 next |
|
1132 fix xa |
|
1133 show "y * (x div y) \<le> x" |
|
1134 apply(subgoal_tac "y * (x div y) + x mod y = x") |
|
1135 apply(rule_tac k = "x mod y" in add_leD1, simp) |
|
1136 apply(simp) |
|
1137 done |
|
1138 qed |
|
1139 |
|
1140 lemma [intro]: "quo [x, 0] = 0" |
|
1141 by(simp add: quo.simps Maxr.simps) |
|
1142 |
|
1143 lemma quo_div: "quo [x, y] = x div y" |
|
1144 by(case_tac "y=0", auto) |
|
1145 |
|
1146 text {* |
|
1147 @{text "rec_noteq"} is the recursive function testing whether its |
|
1148 two arguments are not equal. |
|
1149 *} |
|
1150 definition rec_noteq:: "recf" |
|
1151 where |
|
1152 "rec_noteq = Cn (Suc (Suc 0)) rec_not [Cn (Suc (Suc 0)) |
|
1153 rec_eq [id (Suc (Suc 0)) (0), id (Suc (Suc 0)) |
|
1154 ((Suc 0))]]" |
|
1155 |
|
1156 text {* |
|
1157 The correctness of @{text "rec_noteq"}. |
|
1158 *} |
|
1159 lemma noteq_lemma: |
|
1160 "\<And> x y. rec_exec rec_noteq [x, y] = |
|
1161 (if x \<noteq> y then 1 else 0)" |
|
1162 by(simp add: rec_exec.simps rec_noteq_def) |
|
1163 |
|
1164 declare noteq_lemma[simp] |
|
1165 |
|
1166 text {* |
|
1167 @{text "rec_quo"} is the recursive function used to implement @{text "quo"} |
|
1168 *} |
|
1169 definition rec_quo :: "recf" |
|
1170 where |
|
1171 "rec_quo = (let rR = Cn (Suc (Suc (Suc 0))) rec_conj |
|
1172 [Cn (Suc (Suc (Suc 0))) rec_le |
|
1173 [Cn (Suc (Suc (Suc 0))) rec_mult |
|
1174 [id (Suc (Suc (Suc 0))) (Suc 0), |
|
1175 id (Suc (Suc (Suc 0))) ((Suc (Suc 0)))], |
|
1176 id (Suc (Suc (Suc 0))) (0)], |
|
1177 Cn (Suc (Suc (Suc 0))) rec_noteq |
|
1178 [id (Suc (Suc (Suc 0))) (Suc (0)), |
|
1179 Cn (Suc (Suc (Suc 0))) (constn 0) |
|
1180 [id (Suc (Suc (Suc 0))) (0)]]] |
|
1181 in Cn (Suc (Suc 0)) (rec_maxr rR)) [id (Suc (Suc 0)) |
|
1182 (0),id (Suc (Suc 0)) (Suc (0)), |
|
1183 id (Suc (Suc 0)) (0)]" |
|
1184 |
|
1185 lemma [intro]: "primerec rec_conj (Suc (Suc 0))" |
|
1186 apply(simp add: rec_conj_def) |
|
1187 apply(rule_tac prime_cn, auto)+ |
|
1188 apply(case_tac i, auto intro: prime_id) |
|
1189 done |
|
1190 |
|
1191 lemma [intro]: "primerec rec_noteq (Suc (Suc 0))" |
|
1192 apply(simp add: rec_noteq_def) |
|
1193 apply(rule_tac prime_cn, auto)+ |
|
1194 apply(case_tac i, auto intro: prime_id) |
|
1195 done |
|
1196 |
|
1197 |
|
1198 lemma quo_lemma1: "rec_exec rec_quo [x, y] = quo [x, y]" |
|
1199 proof(simp add: rec_exec.simps rec_quo_def) |
|
1200 let ?rR = "(Cn (Suc (Suc (Suc 0))) rec_conj |
|
1201 [Cn (Suc (Suc (Suc 0))) rec_le |
|
1202 [Cn (Suc (Suc (Suc 0))) rec_mult |
|
1203 [recf.id (Suc (Suc (Suc 0))) (Suc (0)), |
|
1204 recf.id (Suc (Suc (Suc 0))) (Suc (Suc (0)))], |
|
1205 recf.id (Suc (Suc (Suc 0))) (0)], |
|
1206 Cn (Suc (Suc (Suc 0))) rec_noteq |
|
1207 [recf.id (Suc (Suc (Suc 0))) |
|
1208 (Suc (0)), Cn (Suc (Suc (Suc 0))) (constn 0) |
|
1209 [recf.id (Suc (Suc (Suc 0))) (0)]]])" |
|
1210 have "rec_exec (rec_maxr ?rR) ([x, y]@ [ x]) = Maxr (\<lambda> args. 0 < rec_exec ?rR args) [x, y] x" |
|
1211 proof(rule_tac Maxr_lemma, simp) |
|
1212 show "primerec ?rR (Suc (Suc (Suc 0)))" |
|
1213 apply(auto) |
|
1214 apply(case_tac i, auto) |
|
1215 apply(case_tac [!] ia, auto) |
|
1216 apply(case_tac i, auto) |
|
1217 done |
|
1218 qed |
|
1219 hence g1: "rec_exec (rec_maxr ?rR) ([x, y, x]) = |
|
1220 Maxr (\<lambda> args. if rec_exec ?rR args = 0 then False |
|
1221 else True) [x, y] x" |
|
1222 by simp |
|
1223 have g2: "Maxr (\<lambda> args. if rec_exec ?rR args = 0 then False |
|
1224 else True) [x, y] x = quo [x, y]" |
|
1225 apply(simp add: rec_exec.simps) |
|
1226 apply(simp add: Maxr.simps quo.simps, auto) |
|
1227 done |
|
1228 from g1 and g2 show |
|
1229 "rec_exec (rec_maxr ?rR) ([x, y, x]) = quo [x, y]" |
|
1230 by simp |
|
1231 qed |
|
1232 |
|
1233 text {* |
|
1234 The correctness of @{text "quo"}. |
|
1235 *} |
|
1236 lemma quo_lemma2: "rec_exec rec_quo [x, y] = x div y" |
|
1237 using quo_lemma1[of x y] quo_div[of x y] |
|
1238 by simp |
|
1239 |
|
1240 text {* |
|
1241 @{text "rec_mod"} is the recursive function used to implement |
|
1242 the reminder function. |
|
1243 *} |
|
1244 definition rec_mod :: "recf" |
|
1245 where |
|
1246 "rec_mod = Cn (Suc (Suc 0)) rec_minus [id (Suc (Suc 0)) (0), |
|
1247 Cn (Suc (Suc 0)) rec_mult [rec_quo, id (Suc (Suc 0)) |
|
1248 (Suc (0))]]" |
|
1249 |
|
1250 text {* |
|
1251 The correctness of @{text "rec_mod"}: |
|
1252 *} |
|
1253 lemma mod_lemma: "\<And> x y. rec_exec rec_mod [x, y] = (x mod y)" |
|
1254 proof(simp add: rec_exec.simps rec_mod_def quo_lemma2) |
|
1255 fix x y |
|
1256 show "x - x div y * y = x mod (y::nat)" |
|
1257 using mod_div_equality2[of y x] |
|
1258 apply(subgoal_tac "y * (x div y) = (x div y ) * y", arith, simp) |
|
1259 done |
|
1260 qed |
|
1261 |
|
1262 text{* lemmas for embranch function*} |
|
1263 type_synonym ftype = "nat list \<Rightarrow> nat" |
|
1264 type_synonym rtype = "nat list \<Rightarrow> bool" |
|
1265 |
|
1266 text {* |
|
1267 The specifation of the mutli-way branching statement on |
|
1268 page 79 of Boolos's book. |
|
1269 *} |
|
1270 fun Embranch :: "(ftype * rtype) list \<Rightarrow> nat list \<Rightarrow> nat" |
|
1271 where |
|
1272 "Embranch [] xs = 0" | |
|
1273 "Embranch (gc # gcs) xs = ( |
|
1274 let (g, c) = gc in |
|
1275 if c xs then g xs else Embranch gcs xs)" |
|
1276 |
|
1277 fun rec_embranch' :: "(recf * recf) list \<Rightarrow> nat \<Rightarrow> recf" |
|
1278 where |
|
1279 "rec_embranch' [] vl = Cn vl z [id vl (vl - 1)]" | |
|
1280 "rec_embranch' ((rg, rc) # rgcs) vl = Cn vl rec_add |
|
1281 [Cn vl rec_mult [rg, rc], rec_embranch' rgcs vl]" |
|
1282 |
|
1283 text {* |
|
1284 @{text "rec_embrach"} is the recursive function used to implement |
|
1285 @{text "Embranch"}. |
|
1286 *} |
|
1287 fun rec_embranch :: "(recf * recf) list \<Rightarrow> recf" |
|
1288 where |
|
1289 "rec_embranch ((rg, rc) # rgcs) = |
|
1290 (let vl = arity rg in |
|
1291 rec_embranch' ((rg, rc) # rgcs) vl)" |
|
1292 |
|
1293 declare Embranch.simps[simp del] rec_embranch.simps[simp del] |
|
1294 |
|
1295 lemma embranch_all0: |
|
1296 "\<lbrakk>\<forall> j < length rcs. rec_exec (rcs ! j) xs = 0; |
|
1297 length rgs = length rcs; |
|
1298 rcs \<noteq> []; |
|
1299 list_all (\<lambda> rf. primerec rf (length xs)) (rgs @ rcs)\<rbrakk> \<Longrightarrow> |
|
1300 rec_exec (rec_embranch (zip rgs rcs)) xs = 0" |
|
1301 proof(induct rcs arbitrary: rgs, simp, case_tac rgs, simp) |
|
1302 fix a rcs rgs aa list |
|
1303 assume ind: |
|
1304 "\<And>rgs. \<lbrakk>\<forall>j<length rcs. rec_exec (rcs ! j) xs = 0; |
|
1305 length rgs = length rcs; rcs \<noteq> []; |
|
1306 list_all (\<lambda>rf. primerec rf (length xs)) (rgs @ rcs)\<rbrakk> \<Longrightarrow> |
|
1307 rec_exec (rec_embranch (zip rgs rcs)) xs = 0" |
|
1308 and h: "\<forall>j<length (a # rcs). rec_exec ((a # rcs) ! j) xs = 0" |
|
1309 "length rgs = length (a # rcs)" |
|
1310 "a # rcs \<noteq> []" |
|
1311 "list_all (\<lambda>rf. primerec rf (length xs)) (rgs @ a # rcs)" |
|
1312 "rgs = aa # list" |
|
1313 have g: "rcs \<noteq> [] \<Longrightarrow> rec_exec (rec_embranch (zip list rcs)) xs = 0" |
|
1314 using h |
|
1315 by(rule_tac ind, auto) |
|
1316 show "rec_exec (rec_embranch (zip rgs (a # rcs))) xs = 0" |
|
1317 proof(case_tac "rcs = []", simp) |
|
1318 show "rec_exec (rec_embranch (zip rgs [a])) xs = 0" |
|
1319 using h |
|
1320 apply(simp add: rec_embranch.simps rec_exec.simps) |
|
1321 apply(erule_tac x = 0 in allE, simp) |
|
1322 done |
|
1323 next |
|
1324 assume "rcs \<noteq> []" |
|
1325 hence "rec_exec (rec_embranch (zip list rcs)) xs = 0" |
|
1326 using g by simp |
|
1327 thus "rec_exec (rec_embranch (zip rgs (a # rcs))) xs = 0" |
|
1328 using h |
|
1329 apply(simp add: rec_embranch.simps rec_exec.simps) |
|
1330 apply(case_tac rcs, |
|
1331 auto simp: rec_exec.simps rec_embranch.simps) |
|
1332 apply(case_tac list, |
|
1333 auto simp: rec_exec.simps rec_embranch.simps) |
|
1334 done |
|
1335 qed |
|
1336 qed |
|
1337 |
|
1338 |
|
1339 lemma embranch_exec_0: "\<lbrakk>rec_exec aa xs = 0; zip rgs list \<noteq> []; |
|
1340 list_all (\<lambda> rf. primerec rf (length xs)) ([a, aa] @ rgs @ list)\<rbrakk> |
|
1341 \<Longrightarrow> rec_exec (rec_embranch ((a, aa) # zip rgs list)) xs |
|
1342 = rec_exec (rec_embranch (zip rgs list)) xs" |
|
1343 apply(simp add: rec_exec.simps rec_embranch.simps) |
|
1344 apply(case_tac "zip rgs list", simp, case_tac ab, |
|
1345 simp add: rec_embranch.simps rec_exec.simps) |
|
1346 apply(subgoal_tac "arity a = length xs", auto) |
|
1347 apply(subgoal_tac "arity aaa = length xs", auto) |
|
1348 apply(case_tac rgs, simp, case_tac list, simp, simp) |
|
1349 done |
|
1350 |
|
1351 lemma zip_null_iff: "\<lbrakk>length xs = k; length ys = k; zip xs ys = []\<rbrakk> \<Longrightarrow> xs = [] \<and> ys = []" |
|
1352 apply(case_tac xs, simp, simp) |
|
1353 apply(case_tac ys, simp, simp) |
|
1354 done |
|
1355 |
|
1356 lemma zip_null_gr: "\<lbrakk>length xs = k; length ys = k; zip xs ys \<noteq> []\<rbrakk> \<Longrightarrow> 0 < k" |
|
1357 apply(case_tac xs, simp, simp) |
|
1358 done |
|
1359 |
|
1360 lemma Embranch_0: |
|
1361 "\<lbrakk>length rgs = k; length rcs = k; k > 0; |
|
1362 \<forall> j < k. rec_exec (rcs ! j) xs = 0\<rbrakk> \<Longrightarrow> |
|
1363 Embranch (zip (map rec_exec rgs) (map (\<lambda>r args. 0 < rec_exec r args) rcs)) xs = 0" |
|
1364 proof(induct rgs arbitrary: rcs k, simp, simp) |
|
1365 fix a rgs rcs k |
|
1366 assume ind: |
|
1367 "\<And>rcs k. \<lbrakk>length rgs = k; length rcs = k; 0 < k; \<forall>j<k. rec_exec (rcs ! j) xs = 0\<rbrakk> |
|
1368 \<Longrightarrow> Embranch (zip (map rec_exec rgs) (map (\<lambda>r args. 0 < rec_exec r args) rcs)) xs = 0" |
|
1369 and h: "Suc (length rgs) = k" "length rcs = k" |
|
1370 "\<forall>j<k. rec_exec (rcs ! j) xs = 0" |
|
1371 from h show |
|
1372 "Embranch (zip (rec_exec a # map rec_exec rgs) |
|
1373 (map (\<lambda>r args. 0 < rec_exec r args) rcs)) xs = 0" |
|
1374 apply(case_tac rcs, simp, case_tac "rgs = []", simp) |
|
1375 apply(simp add: Embranch.simps) |
|
1376 apply(erule_tac x = 0 in allE, simp) |
|
1377 apply(simp add: Embranch.simps) |
|
1378 apply(erule_tac x = 0 in all_dupE, simp) |
|
1379 apply(rule_tac ind, simp, simp, simp, auto) |
|
1380 apply(erule_tac x = "Suc j" in allE, simp) |
|
1381 done |
|
1382 qed |
|
1383 |
|
1384 text {* |
|
1385 The correctness of @{text "rec_embranch"}. |
|
1386 *} |
|
1387 lemma embranch_lemma: |
|
1388 assumes branch_num: |
|
1389 "length rgs = n" "length rcs = n" "n > 0" |
|
1390 and partition: |
|
1391 "(\<exists> i < n. (rec_exec (rcs ! i) xs = 1 \<and> (\<forall> j < n. j \<noteq> i \<longrightarrow> |
|
1392 rec_exec (rcs ! j) xs = 0)))" |
|
1393 and prime_all: "list_all (\<lambda> rf. primerec rf (length xs)) (rgs @ rcs)" |
|
1394 shows "rec_exec (rec_embranch (zip rgs rcs)) xs = |
|
1395 Embranch (zip (map rec_exec rgs) |
|
1396 (map (\<lambda> r args. 0 < rec_exec r args) rcs)) xs" |
|
1397 using branch_num partition prime_all |
|
1398 proof(induct rgs arbitrary: rcs n, simp) |
|
1399 fix a rgs rcs n |
|
1400 assume ind: |
|
1401 "\<And>rcs n. \<lbrakk>length rgs = n; length rcs = n; 0 < n; |
|
1402 \<exists>i<n. rec_exec (rcs ! i) xs = 1 \<and> (\<forall>j<n. j \<noteq> i \<longrightarrow> rec_exec (rcs ! j) xs = 0); |
|
1403 list_all (\<lambda>rf. primerec rf (length xs)) (rgs @ rcs)\<rbrakk> |
|
1404 \<Longrightarrow> rec_exec (rec_embranch (zip rgs rcs)) xs = |
|
1405 Embranch (zip (map rec_exec rgs) (map (\<lambda>r args. 0 < rec_exec r args) rcs)) xs" |
|
1406 and h: "length (a # rgs) = n" "length (rcs::recf list) = n" "0 < n" |
|
1407 " \<exists>i<n. rec_exec (rcs ! i) xs = 1 \<and> |
|
1408 (\<forall>j<n. j \<noteq> i \<longrightarrow> rec_exec (rcs ! j) xs = 0)" |
|
1409 "list_all (\<lambda>rf. primerec rf (length xs)) ((a # rgs) @ rcs)" |
|
1410 from h show "rec_exec (rec_embranch (zip (a # rgs) rcs)) xs = |
|
1411 Embranch (zip (map rec_exec (a # rgs)) (map (\<lambda>r args. |
|
1412 0 < rec_exec r args) rcs)) xs" |
|
1413 apply(case_tac rcs, simp, simp) |
|
1414 apply(case_tac "rec_exec aa xs = 0") |
|
1415 apply(case_tac [!] "zip rgs list = []", simp) |
|
1416 apply(subgoal_tac "rgs = [] \<and> list = []", simp add: Embranch.simps rec_exec.simps rec_embranch.simps) |
|
1417 apply(rule_tac zip_null_iff, simp, simp, simp) |
|
1418 thm Embranch.simps |
|
1419 proof - |
|
1420 fix aa list |
|
1421 assume g: |
|
1422 "Suc (length rgs) = n" "Suc (length list) = n" |
|
1423 "\<exists>i<n. rec_exec ((aa # list) ! i) xs = Suc 0 \<and> |
|
1424 (\<forall>j<n. j \<noteq> i \<longrightarrow> rec_exec ((aa # list) ! j) xs = 0)" |
|
1425 "primerec a (length xs) \<and> |
|
1426 list_all (\<lambda>rf. primerec rf (length xs)) rgs \<and> |
|
1427 primerec aa (length xs) \<and> |
|
1428 list_all (\<lambda>rf. primerec rf (length xs)) list" |
|
1429 "rec_exec aa xs = 0" "rcs = aa # list" "zip rgs list \<noteq> []" |
|
1430 have "rec_exec (rec_embranch ((a, aa) # zip rgs list)) xs |
|
1431 = rec_exec (rec_embranch (zip rgs list)) xs" |
|
1432 apply(rule embranch_exec_0, simp_all add: g) |
|
1433 done |
|
1434 from g and this show "rec_exec (rec_embranch ((a, aa) # zip rgs list)) xs = |
|
1435 Embranch ((rec_exec a, \<lambda>args. 0 < rec_exec aa args) # |
|
1436 zip (map rec_exec rgs) (map (\<lambda>r args. 0 < rec_exec r args) list)) xs" |
|
1437 apply(simp add: Embranch.simps) |
|
1438 apply(rule_tac n = "n - Suc 0" in ind) |
|
1439 apply(case_tac n, simp, simp) |
|
1440 apply(case_tac n, simp, simp) |
|
1441 apply(case_tac n, simp, simp add: zip_null_gr ) |
|
1442 apply(auto) |
|
1443 apply(case_tac i, simp, simp) |
|
1444 apply(rule_tac x = nat in exI, simp) |
|
1445 apply(rule_tac allI, erule_tac x = "Suc j" in allE, simp) |
|
1446 done |
|
1447 next |
|
1448 fix aa list |
|
1449 assume g: "Suc (length rgs) = n" "Suc (length list) = n" |
|
1450 "\<exists>i<n. rec_exec ((aa # list) ! i) xs = Suc 0 \<and> |
|
1451 (\<forall>j<n. j \<noteq> i \<longrightarrow> rec_exec ((aa # list) ! j) xs = 0)" |
|
1452 "primerec a (length xs) \<and> list_all (\<lambda>rf. primerec rf (length xs)) rgs \<and> |
|
1453 primerec aa (length xs) \<and> list_all (\<lambda>rf. primerec rf (length xs)) list" |
|
1454 "rcs = aa # list" "rec_exec aa xs \<noteq> 0" "zip rgs list = []" |
|
1455 thus "rec_exec (rec_embranch ((a, aa) # zip rgs list)) xs = |
|
1456 Embranch ((rec_exec a, \<lambda>args. 0 < rec_exec aa args) # |
|
1457 zip (map rec_exec rgs) (map (\<lambda>r args. 0 < rec_exec r args) list)) xs" |
|
1458 apply(subgoal_tac "rgs = [] \<and> list = []", simp) |
|
1459 prefer 2 |
|
1460 apply(rule_tac zip_null_iff, simp, simp, simp) |
|
1461 apply(simp add: rec_exec.simps rec_embranch.simps Embranch.simps, auto) |
|
1462 done |
|
1463 next |
|
1464 fix aa list |
|
1465 assume g: "Suc (length rgs) = n" "Suc (length list) = n" |
|
1466 "\<exists>i<n. rec_exec ((aa # list) ! i) xs = Suc 0 \<and> |
|
1467 (\<forall>j<n. j \<noteq> i \<longrightarrow> rec_exec ((aa # list) ! j) xs = 0)" |
|
1468 "primerec a (length xs) \<and> list_all (\<lambda>rf. primerec rf (length xs)) rgs |
|
1469 \<and> primerec aa (length xs) \<and> list_all (\<lambda>rf. primerec rf (length xs)) list" |
|
1470 "rcs = aa # list" "rec_exec aa xs \<noteq> 0" "zip rgs list \<noteq> []" |
|
1471 have "rec_exec aa xs = Suc 0" |
|
1472 using g |
|
1473 apply(case_tac "rec_exec aa xs", simp, auto) |
|
1474 done |
|
1475 moreover have "rec_exec (rec_embranch' (zip rgs list) (length xs)) xs = 0" |
|
1476 proof - |
|
1477 have "rec_embranch' (zip rgs list) (length xs) = rec_embranch (zip rgs list)" |
|
1478 using g |
|
1479 apply(case_tac "zip rgs list", simp, case_tac ab) |
|
1480 apply(simp add: rec_embranch.simps) |
|
1481 apply(subgoal_tac "arity aaa = length xs", simp, auto) |
|
1482 apply(case_tac rgs, simp, simp, case_tac list, simp, simp) |
|
1483 done |
|
1484 moreover have "rec_exec (rec_embranch (zip rgs list)) xs = 0" |
|
1485 proof(rule embranch_all0) |
|
1486 show " \<forall>j<length list. rec_exec (list ! j) xs = 0" |
|
1487 using g |
|
1488 apply(auto) |
|
1489 apply(case_tac i, simp) |
|
1490 apply(erule_tac x = "Suc j" in allE, simp) |
|
1491 apply(simp) |
|
1492 apply(erule_tac x = 0 in allE, simp) |
|
1493 done |
|
1494 next |
|
1495 show "length rgs = length list" |
|
1496 using g |
|
1497 apply(case_tac n, simp, simp) |
|
1498 done |
|
1499 next |
|
1500 show "list \<noteq> []" |
|
1501 using g |
|
1502 apply(case_tac list, simp, simp) |
|
1503 done |
|
1504 next |
|
1505 show "list_all (\<lambda>rf. primerec rf (length xs)) (rgs @ list)" |
|
1506 using g |
|
1507 apply auto |
|
1508 done |
|
1509 qed |
|
1510 ultimately show "rec_exec (rec_embranch' (zip rgs list) (length xs)) xs = 0" |
|
1511 by simp |
|
1512 qed |
|
1513 moreover have |
|
1514 "Embranch (zip (map rec_exec rgs) |
|
1515 (map (\<lambda>r args. 0 < rec_exec r args) list)) xs = 0" |
|
1516 using g |
|
1517 apply(rule_tac k = "length rgs" in Embranch_0) |
|
1518 apply(simp, case_tac n, simp, simp) |
|
1519 apply(case_tac rgs, simp, simp) |
|
1520 apply(auto) |
|
1521 apply(case_tac i, simp) |
|
1522 apply(erule_tac x = "Suc j" in allE, simp) |
|
1523 apply(simp) |
|
1524 apply(rule_tac x = 0 in allE, auto) |
|
1525 done |
|
1526 moreover have "arity a = length xs" |
|
1527 using g |
|
1528 apply(auto) |
|
1529 done |
|
1530 ultimately show "rec_exec (rec_embranch ((a, aa) # zip rgs list)) xs = |
|
1531 Embranch ((rec_exec a, \<lambda>args. 0 < rec_exec aa args) # |
|
1532 zip (map rec_exec rgs) (map (\<lambda>r args. 0 < rec_exec r args) list)) xs" |
|
1533 apply(simp add: rec_exec.simps rec_embranch.simps Embranch.simps) |
|
1534 done |
|
1535 qed |
|
1536 qed |
|
1537 |
|
1538 text{* |
|
1539 @{text "prime n"} means @{text "n"} is a prime number. |
|
1540 *} |
|
1541 fun Prime :: "nat \<Rightarrow> bool" |
|
1542 where |
|
1543 "Prime x = (1 < x \<and> (\<forall> u < x. (\<forall> v < x. u * v \<noteq> x)))" |
|
1544 |
|
1545 declare Prime.simps [simp del] |
|
1546 |
|
1547 lemma primerec_all1: |
|
1548 "primerec (rec_all rt rf) n \<Longrightarrow> primerec rt n" |
|
1549 by (simp add: primerec_all) |
|
1550 |
|
1551 lemma primerec_all2: "primerec (rec_all rt rf) n \<Longrightarrow> |
|
1552 primerec rf (Suc n)" |
|
1553 by(insert primerec_all[of rt rf n], simp) |
|
1554 |
|
1555 text {* |
|
1556 @{text "rec_prime"} is the recursive function used to implement |
|
1557 @{text "Prime"}. |
|
1558 *} |
|
1559 definition rec_prime :: "recf" |
|
1560 where |
|
1561 "rec_prime = Cn (Suc 0) rec_conj |
|
1562 [Cn (Suc 0) rec_less [constn 1, id (Suc 0) (0)], |
|
1563 rec_all (Cn 1 rec_minus [id 1 0, constn 1]) |
|
1564 (rec_all (Cn 2 rec_minus [id 2 0, Cn 2 (constn 1) |
|
1565 [id 2 0]]) (Cn 3 rec_noteq |
|
1566 [Cn 3 rec_mult [id 3 1, id 3 2], id 3 0]))]" |
|
1567 |
|
1568 (* |
|
1569 lemma prime_lemma1: |
|
1570 "(rec_exec rec_prime [x] = Suc 0) \<or> |
|
1571 (rec_exec rec_prime [x] = 0)" |
|
1572 apply(auto simp: rec_exec.simps rec_prime_def) |
|
1573 done |
|
1574 *) |
|
1575 declare numeral_2_eq_2[simp del] numeral_3_eq_3[simp del] |
|
1576 |
|
1577 lemma exec_tmp: |
|
1578 "rec_exec (rec_all (Cn 2 rec_minus [recf.id 2 0, Cn 2 (constn (Suc 0)) [recf.id 2 0]]) |
|
1579 (Cn 3 rec_noteq [Cn 3 rec_mult [recf.id 3 (Suc 0), recf.id 3 2], recf.id 3 0])) [x, k] = |
|
1580 ((if (\<forall>w\<le>rec_exec (Cn 2 rec_minus [recf.id 2 0, Cn 2 (constn (Suc 0)) [recf.id 2 0]]) ([x, k]). |
|
1581 0 < rec_exec (Cn 3 rec_noteq [Cn 3 rec_mult [recf.id 3 (Suc 0), recf.id 3 2], recf.id 3 0]) |
|
1582 ([x, k] @ [w])) then 1 else 0))" |
|
1583 apply(rule_tac all_lemma) |
|
1584 apply(auto) |
|
1585 apply(case_tac [!] i, auto) |
|
1586 apply(case_tac ia, auto simp: numeral_3_eq_3 numeral_2_eq_2) |
|
1587 done |
|
1588 |
|
1589 text {* |
|
1590 The correctness of @{text "Prime"}. |
|
1591 *} |
|
1592 lemma prime_lemma: "rec_exec rec_prime [x] = (if Prime x then 1 else 0)" |
|
1593 proof(simp add: rec_exec.simps rec_prime_def) |
|
1594 let ?rt1 = "(Cn 2 rec_minus [recf.id 2 0, |
|
1595 Cn 2 (constn (Suc 0)) [recf.id 2 0]])" |
|
1596 let ?rf1 = "(Cn 3 rec_noteq [Cn 3 rec_mult |
|
1597 [recf.id 3 (Suc 0), recf.id 3 2], recf.id 3 (0)])" |
|
1598 let ?rt2 = "(Cn (Suc 0) rec_minus |
|
1599 [recf.id (Suc 0) 0, constn (Suc 0)])" |
|
1600 let ?rf2 = "rec_all ?rt1 ?rf1" |
|
1601 have h1: "rec_exec (rec_all ?rt2 ?rf2) ([x]) = |
|
1602 (if (\<forall>k\<le>rec_exec ?rt2 ([x]). 0 < rec_exec ?rf2 ([x] @ [k])) then 1 else 0)" |
|
1603 proof(rule_tac all_lemma, simp_all) |
|
1604 show "primerec ?rf2 (Suc (Suc 0))" |
|
1605 apply(rule_tac primerec_all_iff) |
|
1606 apply(auto) |
|
1607 apply(case_tac [!] i, auto simp: numeral_2_eq_2) |
|
1608 apply(case_tac ia, auto simp: numeral_3_eq_3) |
|
1609 done |
|
1610 next |
|
1611 show "primerec (Cn (Suc 0) rec_minus |
|
1612 [recf.id (Suc 0) 0, constn (Suc 0)]) (Suc 0)" |
|
1613 apply(auto) |
|
1614 apply(case_tac i, auto) |
|
1615 done |
|
1616 qed |
|
1617 from h1 show |
|
1618 "(Suc 0 < x \<longrightarrow> (rec_exec (rec_all ?rt2 ?rf2) [x] = 0 \<longrightarrow> |
|
1619 \<not> Prime x) \<and> |
|
1620 (0 < rec_exec (rec_all ?rt2 ?rf2) [x] \<longrightarrow> Prime x)) \<and> |
|
1621 (\<not> Suc 0 < x \<longrightarrow> \<not> Prime x \<and> (rec_exec (rec_all ?rt2 ?rf2) [x] = 0 |
|
1622 \<longrightarrow> \<not> Prime x))" |
|
1623 apply(auto simp:rec_exec.simps) |
|
1624 apply(simp add: exec_tmp rec_exec.simps) |
|
1625 proof - |
|
1626 assume "\<forall>k\<le>x - Suc 0. (0::nat) < (if \<forall>w\<le>x - Suc 0. |
|
1627 0 < (if k * w \<noteq> x then 1 else (0 :: nat)) then 1 else 0)" "Suc 0 < x" |
|
1628 thus "Prime x" |
|
1629 apply(simp add: rec_exec.simps split: if_splits) |
|
1630 apply(simp add: Prime.simps, auto) |
|
1631 apply(erule_tac x = u in allE, auto) |
|
1632 apply(case_tac u, simp, case_tac nat, simp, simp) |
|
1633 apply(case_tac v, simp, case_tac nat, simp, simp) |
|
1634 done |
|
1635 next |
|
1636 assume "\<not> Suc 0 < x" "Prime x" |
|
1637 thus "False" |
|
1638 apply(simp add: Prime.simps) |
|
1639 done |
|
1640 next |
|
1641 fix k |
|
1642 assume "rec_exec (rec_all ?rt1 ?rf1) |
|
1643 [x, k] = 0" "k \<le> x - Suc 0" "Prime x" |
|
1644 thus "False" |
|
1645 apply(simp add: exec_tmp rec_exec.simps Prime.simps split: if_splits) |
|
1646 done |
|
1647 next |
|
1648 fix k |
|
1649 assume "rec_exec (rec_all ?rt1 ?rf1) |
|
1650 [x, k] = 0" "k \<le> x - Suc 0" "Prime x" |
|
1651 thus "False" |
|
1652 apply(simp add: exec_tmp rec_exec.simps Prime.simps split: if_splits) |
|
1653 done |
|
1654 qed |
|
1655 qed |
|
1656 |
|
1657 definition rec_dummyfac :: "recf" |
|
1658 where |
|
1659 "rec_dummyfac = Pr 1 (constn 1) |
|
1660 (Cn 3 rec_mult [id 3 2, Cn 3 s [id 3 1]])" |
|
1661 |
|
1662 text {* |
|
1663 The recursive function used to implment factorization. |
|
1664 *} |
|
1665 definition rec_fac :: "recf" |
|
1666 where |
|
1667 "rec_fac = Cn 1 rec_dummyfac [id 1 0, id 1 0]" |
|
1668 |
|
1669 text {* |
|
1670 Formal specification of factorization. |
|
1671 *} |
|
1672 fun fac :: "nat \<Rightarrow> nat" ("_!" [100] 99) |
|
1673 where |
|
1674 "fac 0 = 1" | |
|
1675 "fac (Suc x) = (Suc x) * fac x" |
|
1676 |
|
1677 lemma [simp]: "rec_exec rec_dummyfac [0, 0] = Suc 0" |
|
1678 by(simp add: rec_dummyfac_def rec_exec.simps) |
|
1679 |
|
1680 lemma rec_cn_simp: "rec_exec (Cn n f gs) xs = |
|
1681 (let rgs = map (\<lambda> g. rec_exec g xs) gs in |
|
1682 rec_exec f rgs)" |
|
1683 by(simp add: rec_exec.simps) |
|
1684 |
|
1685 lemma rec_id_simp: "rec_exec (id m n) xs = xs ! n" |
|
1686 by(simp add: rec_exec.simps) |
|
1687 |
|
1688 lemma fac_dummy: "rec_exec rec_dummyfac [x, y] = y !" |
|
1689 apply(induct y) |
|
1690 apply(auto simp: rec_dummyfac_def rec_exec.simps) |
|
1691 done |
|
1692 |
|
1693 text {* |
|
1694 The correctness of @{text "rec_fac"}. |
|
1695 *} |
|
1696 lemma fac_lemma: "rec_exec rec_fac [x] = x!" |
|
1697 apply(simp add: rec_fac_def rec_exec.simps fac_dummy) |
|
1698 done |
|
1699 |
|
1700 declare fac.simps[simp del] |
|
1701 |
|
1702 text {* |
|
1703 @{text "Np x"} returns the first prime number after @{text "x"}. |
|
1704 *} |
|
1705 fun Np ::"nat \<Rightarrow> nat" |
|
1706 where |
|
1707 "Np x = Min {y. y \<le> Suc (x!) \<and> x < y \<and> Prime y}" |
|
1708 |
|
1709 declare Np.simps[simp del] rec_Minr.simps[simp del] |
|
1710 |
|
1711 text {* |
|
1712 @{text "rec_np"} is the recursive function used to implement |
|
1713 @{text "Np"}. |
|
1714 *} |
|
1715 definition rec_np :: "recf" |
|
1716 where |
|
1717 "rec_np = (let Rr = Cn 2 rec_conj [Cn 2 rec_less [id 2 0, id 2 1], |
|
1718 Cn 2 rec_prime [id 2 1]] |
|
1719 in Cn 1 (rec_Minr Rr) [id 1 0, Cn 1 s [rec_fac]])" |
|
1720 |
|
1721 lemma [simp]: "n < Suc (n!)" |
|
1722 apply(induct n, simp) |
|
1723 apply(simp add: fac.simps) |
|
1724 apply(case_tac n, auto simp: fac.simps) |
|
1725 done |
|
1726 |
|
1727 lemma divsor_ex: |
|
1728 "\<lbrakk>\<not> Prime x; x > Suc 0\<rbrakk> \<Longrightarrow> (\<exists> u > Suc 0. (\<exists> v > Suc 0. u * v = x))" |
|
1729 by(auto simp: Prime.simps) |
|
1730 |
|
1731 lemma divsor_prime_ex: "\<lbrakk>\<not> Prime x; x > Suc 0\<rbrakk> \<Longrightarrow> |
|
1732 \<exists> p. Prime p \<and> p dvd x" |
|
1733 apply(induct x rule: wf_induct[where r = "measure (\<lambda> y. y)"], simp) |
|
1734 apply(drule_tac divsor_ex, simp, auto) |
|
1735 apply(erule_tac x = u in allE, simp) |
|
1736 apply(case_tac "Prime u", simp) |
|
1737 apply(rule_tac x = u in exI, simp, auto) |
|
1738 done |
|
1739 |
|
1740 lemma [intro]: "0 < n!" |
|
1741 apply(induct n) |
|
1742 apply(auto simp: fac.simps) |
|
1743 done |
|
1744 |
|
1745 lemma fac_Suc: "Suc n! = (Suc n) * (n!)" by(simp add: fac.simps) |
|
1746 |
|
1747 lemma fac_dvd: "\<lbrakk>0 < q; q \<le> n\<rbrakk> \<Longrightarrow> q dvd n!" |
|
1748 apply(induct n, simp) |
|
1749 apply(case_tac "q \<le> n", simp add: fac_Suc) |
|
1750 apply(subgoal_tac "q = Suc n", simp only: fac_Suc) |
|
1751 apply(rule_tac dvd_mult2, simp, simp) |
|
1752 done |
|
1753 |
|
1754 lemma fac_dvd2: "\<lbrakk>Suc 0 < q; q dvd n!; q \<le> n\<rbrakk> \<Longrightarrow> \<not> q dvd Suc (n!)" |
|
1755 proof(auto simp: dvd_def) |
|
1756 fix k ka |
|
1757 assume h1: "Suc 0 < q" "q \<le> n" |
|
1758 and h2: "Suc (q * k) = q * ka" |
|
1759 have "k < ka" |
|
1760 proof - |
|
1761 have "q * k < q * ka" |
|
1762 using h2 by arith |
|
1763 thus "k < ka" |
|
1764 using h1 |
|
1765 by(auto) |
|
1766 qed |
|
1767 hence "\<exists>d. d > 0 \<and> ka = d + k" |
|
1768 by(rule_tac x = "ka - k" in exI, simp) |
|
1769 from this obtain d where "d > 0 \<and> ka = d + k" .. |
|
1770 from h2 and this and h1 show "False" |
|
1771 by(simp add: add_mult_distrib2) |
|
1772 qed |
|
1773 |
|
1774 lemma prime_ex: "\<exists> p. n < p \<and> p \<le> Suc (n!) \<and> Prime p" |
|
1775 proof(cases "Prime (n! + 1)") |
|
1776 case True thus "?thesis" |
|
1777 by(rule_tac x = "Suc (n!)" in exI, simp) |
|
1778 next |
|
1779 assume h: "\<not> Prime (n! + 1)" |
|
1780 hence "\<exists> p. Prime p \<and> p dvd (n! + 1)" |
|
1781 by(erule_tac divsor_prime_ex, auto) |
|
1782 from this obtain q where k: "Prime q \<and> q dvd (n! + 1)" .. |
|
1783 thus "?thesis" |
|
1784 proof(cases "q > n") |
|
1785 case True thus "?thesis" |
|
1786 using k |
|
1787 apply(rule_tac x = q in exI, auto) |
|
1788 apply(rule_tac dvd_imp_le, auto) |
|
1789 done |
|
1790 next |
|
1791 case False thus "?thesis" |
|
1792 proof - |
|
1793 assume g: "\<not> n < q" |
|
1794 have j: "q > Suc 0" |
|
1795 using k by(case_tac q, auto simp: Prime.simps) |
|
1796 hence "q dvd n!" |
|
1797 using g |
|
1798 apply(rule_tac fac_dvd, auto) |
|
1799 done |
|
1800 hence "\<not> q dvd Suc (n!)" |
|
1801 using g j |
|
1802 by(rule_tac fac_dvd2, auto) |
|
1803 thus "?thesis" |
|
1804 using k by simp |
|
1805 qed |
|
1806 qed |
|
1807 qed |
|
1808 |
|
1809 lemma Suc_Suc_induct[elim!]: "\<lbrakk>i < Suc (Suc 0); |
|
1810 primerec (ys ! 0) n; primerec (ys ! 1) n\<rbrakk> \<Longrightarrow> primerec (ys ! i) n" |
|
1811 by(case_tac i, auto) |
|
1812 |
|
1813 lemma [intro]: "primerec rec_prime (Suc 0)" |
|
1814 apply(auto simp: rec_prime_def, auto) |
|
1815 apply(rule_tac primerec_all_iff, auto, auto) |
|
1816 apply(rule_tac primerec_all_iff, auto, auto simp: |
|
1817 numeral_2_eq_2 numeral_3_eq_3) |
|
1818 done |
|
1819 |
|
1820 text {* |
|
1821 The correctness of @{text "rec_np"}. |
|
1822 *} |
|
1823 lemma np_lemma: "rec_exec rec_np [x] = Np x" |
|
1824 proof(auto simp: rec_np_def rec_exec.simps Let_def fac_lemma) |
|
1825 let ?rr = "(Cn 2 rec_conj [Cn 2 rec_less [recf.id 2 0, |
|
1826 recf.id 2 (Suc 0)], Cn 2 rec_prime [recf.id 2 (Suc 0)]])" |
|
1827 let ?R = "\<lambda> zs. zs ! 0 < zs ! 1 \<and> Prime (zs ! 1)" |
|
1828 have g1: "rec_exec (rec_Minr ?rr) ([x] @ [Suc (x!)]) = |
|
1829 Minr (\<lambda> args. 0 < rec_exec ?rr args) [x] (Suc (x!))" |
|
1830 by(rule_tac Minr_lemma, auto simp: rec_exec.simps |
|
1831 prime_lemma, auto simp: numeral_2_eq_2 numeral_3_eq_3) |
|
1832 have g2: "Minr (\<lambda> args. 0 < rec_exec ?rr args) [x] (Suc (x!)) = Np x" |
|
1833 using prime_ex[of x] |
|
1834 apply(auto simp: Minr.simps Np.simps rec_exec.simps) |
|
1835 apply(erule_tac x = p in allE, simp add: prime_lemma) |
|
1836 apply(simp add: prime_lemma split: if_splits) |
|
1837 apply(subgoal_tac |
|
1838 "{uu. (Prime uu \<longrightarrow> (x < uu \<longrightarrow> uu \<le> Suc (x!)) \<and> x < uu) \<and> Prime uu} |
|
1839 = {y. y \<le> Suc (x!) \<and> x < y \<and> Prime y}", auto) |
|
1840 done |
|
1841 from g1 and g2 show "rec_exec (rec_Minr ?rr) ([x, Suc (x!)]) = Np x" |
|
1842 by simp |
|
1843 qed |
|
1844 |
|
1845 text {*lemmas for power*} |
|
1846 text {* |
|
1847 @{text "rec_power"} is the recursive function used to implement |
|
1848 power function. |
|
1849 *} |
|
1850 definition rec_power :: "recf" |
|
1851 where |
|
1852 "rec_power = Pr 1 (constn 1) (Cn 3 rec_mult [id 3 0, id 3 2])" |
|
1853 |
|
1854 text {* |
|
1855 The correctness of @{text "rec_power"}. |
|
1856 *} |
|
1857 lemma power_lemma: "rec_exec rec_power [x, y] = x^y" |
|
1858 by(induct y, auto simp: rec_exec.simps rec_power_def) |
|
1859 |
|
1860 text{* |
|
1861 @{text "Pi k"} returns the @{text "k"}-th prime number. |
|
1862 *} |
|
1863 fun Pi :: "nat \<Rightarrow> nat" |
|
1864 where |
|
1865 "Pi 0 = 2" | |
|
1866 "Pi (Suc x) = Np (Pi x)" |
|
1867 |
|
1868 definition rec_dummy_pi :: "recf" |
|
1869 where |
|
1870 "rec_dummy_pi = Pr 1 (constn 2) (Cn 3 rec_np [id 3 2])" |
|
1871 |
|
1872 text {* |
|
1873 @{text "rec_pi"} is the recursive function used to implement |
|
1874 @{text "Pi"}. |
|
1875 *} |
|
1876 definition rec_pi :: "recf" |
|
1877 where |
|
1878 "rec_pi = Cn 1 rec_dummy_pi [id 1 0, id 1 0]" |
|
1879 |
|
1880 lemma pi_dummy_lemma: "rec_exec rec_dummy_pi [x, y] = Pi y" |
|
1881 apply(induct y) |
|
1882 by(auto simp: rec_exec.simps rec_dummy_pi_def Pi.simps np_lemma) |
|
1883 |
|
1884 text {* |
|
1885 The correctness of @{text "rec_pi"}. |
|
1886 *} |
|
1887 lemma pi_lemma: "rec_exec rec_pi [x] = Pi x" |
|
1888 apply(simp add: rec_pi_def rec_exec.simps pi_dummy_lemma) |
|
1889 done |
|
1890 |
|
1891 text{*follows: lemmas for lo*} |
|
1892 fun loR :: "nat list \<Rightarrow> bool" |
|
1893 where |
|
1894 "loR [x, y, u] = (x mod (y^u) = 0)" |
|
1895 |
|
1896 declare loR.simps[simp del] |
|
1897 |
|
1898 text {* |
|
1899 @{text "Lo"} specifies the @{text "lo"} function given on page 79 of |
|
1900 Boolos's book. It is one of the two notions of integeral logarithmatic |
|
1901 operation on that page. The other is @{text "lg"}. |
|
1902 *} |
|
1903 fun lo :: " nat \<Rightarrow> nat \<Rightarrow> nat" |
|
1904 where |
|
1905 "lo x y = (if x > 1 \<and> y > 1 \<and> {u. loR [x, y, u]} \<noteq> {} then Max {u. loR [x, y, u]} |
|
1906 else 0)" |
|
1907 |
|
1908 declare lo.simps[simp del] |
|
1909 |
|
1910 lemma [elim]: "primerec rf n \<Longrightarrow> n > 0" |
|
1911 apply(induct rule: primerec.induct, auto) |
|
1912 done |
|
1913 |
|
1914 lemma primerec_sigma[intro!]: |
|
1915 "\<lbrakk>n > Suc 0; primerec rf n\<rbrakk> \<Longrightarrow> |
|
1916 primerec (rec_sigma rf) n" |
|
1917 apply(simp add: rec_sigma.simps) |
|
1918 apply(auto, auto simp: nth_append) |
|
1919 done |
|
1920 |
|
1921 lemma [intro!]: "\<lbrakk>primerec rf n; n > 0\<rbrakk> \<Longrightarrow> primerec (rec_maxr rf) n" |
|
1922 apply(simp add: rec_maxr.simps) |
|
1923 apply(rule_tac prime_cn, auto) |
|
1924 apply(rule_tac primerec_all_iff, auto, auto simp: nth_append) |
|
1925 done |
|
1926 |
|
1927 lemma Suc_Suc_Suc_induct[elim!]: |
|
1928 "\<lbrakk>i < Suc (Suc (Suc (0::nat))); primerec (ys ! 0) n; |
|
1929 primerec (ys ! 1) n; |
|
1930 primerec (ys ! 2) n\<rbrakk> \<Longrightarrow> primerec (ys ! i) n" |
|
1931 apply(case_tac i, auto, case_tac nat, simp, simp add: numeral_2_eq_2) |
|
1932 done |
|
1933 |
|
1934 lemma [intro]: "primerec rec_quo (Suc (Suc 0))" |
|
1935 apply(simp add: rec_quo_def) |
|
1936 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
1937 @{thm prime_id}] 1*}, auto+)+ |
|
1938 done |
|
1939 |
|
1940 lemma [intro]: "primerec rec_mod (Suc (Suc 0))" |
|
1941 apply(simp add: rec_mod_def) |
|
1942 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
1943 @{thm prime_id}] 1*}, auto+)+ |
|
1944 done |
|
1945 |
|
1946 lemma [intro]: "primerec rec_power (Suc (Suc 0))" |
|
1947 apply(simp add: rec_power_def numeral_2_eq_2 numeral_3_eq_3) |
|
1948 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
1949 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
1950 done |
|
1951 |
|
1952 text {* |
|
1953 @{text "rec_lo"} is the recursive function used to implement @{text "Lo"}. |
|
1954 *} |
|
1955 definition rec_lo :: "recf" |
|
1956 where |
|
1957 "rec_lo = (let rR = Cn 3 rec_eq [Cn 3 rec_mod [id 3 0, |
|
1958 Cn 3 rec_power [id 3 1, id 3 2]], |
|
1959 Cn 3 (constn 0) [id 3 1]] in |
|
1960 let rb = Cn 2 (rec_maxr rR) [id 2 0, id 2 1, id 2 0] in |
|
1961 let rcond = Cn 2 rec_conj [Cn 2 rec_less [Cn 2 (constn 1) |
|
1962 [id 2 0], id 2 0], |
|
1963 Cn 2 rec_less [Cn 2 (constn 1) |
|
1964 [id 2 0], id 2 1]] in |
|
1965 let rcond2 = Cn 2 rec_minus |
|
1966 [Cn 2 (constn 1) [id 2 0], rcond] |
|
1967 in Cn 2 rec_add [Cn 2 rec_mult [rb, rcond], |
|
1968 Cn 2 rec_mult [Cn 2 (constn 0) [id 2 0], rcond2]])" |
|
1969 |
|
1970 lemma rec_lo_Maxr_lor: |
|
1971 "\<lbrakk>Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow> |
|
1972 rec_exec rec_lo [x, y] = Maxr loR [x, y] x" |
|
1973 proof(auto simp: rec_exec.simps rec_lo_def Let_def |
|
1974 numeral_2_eq_2 numeral_3_eq_3) |
|
1975 let ?rR = "(Cn (Suc (Suc (Suc 0))) rec_eq |
|
1976 [Cn (Suc (Suc (Suc 0))) rec_mod [recf.id (Suc (Suc (Suc 0))) 0, |
|
1977 Cn (Suc (Suc (Suc 0))) rec_power [recf.id (Suc (Suc (Suc 0))) |
|
1978 (Suc 0), recf.id (Suc (Suc (Suc 0))) (Suc (Suc 0))]], |
|
1979 Cn (Suc (Suc (Suc 0))) (constn 0) [recf.id (Suc (Suc (Suc 0))) (Suc 0)]])" |
|
1980 have h: "rec_exec (rec_maxr ?rR) ([x, y] @ [x]) = |
|
1981 Maxr (\<lambda> args. 0 < rec_exec ?rR args) [x, y] x" |
|
1982 by(rule_tac Maxr_lemma, auto simp: rec_exec.simps |
|
1983 mod_lemma power_lemma, auto simp: numeral_2_eq_2 numeral_3_eq_3) |
|
1984 have "Maxr loR [x, y] x = Maxr (\<lambda> args. 0 < rec_exec ?rR args) [x, y] x" |
|
1985 apply(simp add: rec_exec.simps mod_lemma power_lemma) |
|
1986 apply(simp add: Maxr.simps loR.simps) |
|
1987 done |
|
1988 from h and this show "rec_exec (rec_maxr ?rR) [x, y, x] = |
|
1989 Maxr loR [x, y] x" |
|
1990 apply(simp) |
|
1991 done |
|
1992 qed |
|
1993 |
|
1994 lemma [simp]: "Max {ya. ya = 0 \<and> loR [0, y, ya]} = 0" |
|
1995 apply(rule_tac Max_eqI, auto simp: loR.simps) |
|
1996 done |
|
1997 |
|
1998 lemma [simp]: "Suc 0 < y \<Longrightarrow> Suc (Suc 0) < y * y" |
|
1999 apply(induct y, simp) |
|
2000 apply(case_tac y, simp, simp) |
|
2001 done |
|
2002 |
|
2003 lemma less_mult: "\<lbrakk>x > 0; y > Suc 0\<rbrakk> \<Longrightarrow> x < y * x" |
|
2004 apply(case_tac y, simp, simp) |
|
2005 done |
|
2006 |
|
2007 lemma x_less_exp: "\<lbrakk>y > Suc 0\<rbrakk> \<Longrightarrow> x < y^x" |
|
2008 apply(induct x, simp, simp) |
|
2009 apply(case_tac x, simp, auto) |
|
2010 apply(rule_tac y = "y* y^nat" in le_less_trans, simp) |
|
2011 apply(rule_tac less_mult, auto) |
|
2012 done |
|
2013 |
|
2014 lemma le_mult: "y \<noteq> (0::nat) \<Longrightarrow> x \<le> x * y" |
|
2015 by(induct y, simp, simp) |
|
2016 |
|
2017 lemma uplimit_loR: "\<lbrakk>Suc 0 < x; Suc 0 < y; loR [x, y, xa]\<rbrakk> \<Longrightarrow> |
|
2018 xa \<le> x" |
|
2019 apply(simp add: loR.simps) |
|
2020 apply(rule_tac classical, auto) |
|
2021 apply(subgoal_tac "xa < y^xa") |
|
2022 apply(subgoal_tac "y^xa \<le> y^xa * q", simp) |
|
2023 apply(rule_tac le_mult, case_tac q, simp, simp) |
|
2024 apply(rule_tac x_less_exp, simp) |
|
2025 done |
|
2026 |
|
2027 lemma [simp]: "\<lbrakk>xa \<le> x; loR [x, y, xa]; Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow> |
|
2028 {u. loR [x, y, u]} = {ya. ya \<le> x \<and> loR [x, y, ya]}" |
|
2029 apply(rule_tac Collect_cong, auto) |
|
2030 apply(erule_tac uplimit_loR, simp, simp) |
|
2031 done |
|
2032 |
|
2033 lemma Maxr_lo: "\<lbrakk>Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow> |
|
2034 Maxr loR [x, y] x = lo x y" |
|
2035 apply(simp add: Maxr.simps lo.simps, auto) |
|
2036 apply(erule_tac x = xa in allE, simp, simp add: uplimit_loR) |
|
2037 done |
|
2038 |
|
2039 lemma lo_lemma': "\<lbrakk>Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow> |
|
2040 rec_exec rec_lo [x, y] = lo x y" |
|
2041 by(simp add: Maxr_lo rec_lo_Maxr_lor) |
|
2042 |
|
2043 lemma lo_lemma'': "\<lbrakk>\<not> Suc 0 < x\<rbrakk> \<Longrightarrow> rec_exec rec_lo [x, y] = lo x y" |
|
2044 apply(case_tac x, auto simp: rec_exec.simps rec_lo_def |
|
2045 Let_def lo.simps) |
|
2046 done |
|
2047 |
|
2048 lemma lo_lemma''': "\<lbrakk>\<not> Suc 0 < y\<rbrakk> \<Longrightarrow> rec_exec rec_lo [x, y] = lo x y" |
|
2049 apply(case_tac y, auto simp: rec_exec.simps rec_lo_def |
|
2050 Let_def lo.simps) |
|
2051 done |
|
2052 |
|
2053 text {* |
|
2054 The correctness of @{text "rec_lo"}: |
|
2055 *} |
|
2056 lemma lo_lemma: "rec_exec rec_lo [x, y] = lo x y" |
|
2057 apply(case_tac "Suc 0 < x \<and> Suc 0 < y") |
|
2058 apply(auto simp: lo_lemma' lo_lemma'' lo_lemma''') |
|
2059 done |
|
2060 |
|
2061 fun lgR :: "nat list \<Rightarrow> bool" |
|
2062 where |
|
2063 "lgR [x, y, u] = (y^u \<le> x)" |
|
2064 |
|
2065 text {* |
|
2066 @{text "lg"} specifies the @{text "lg"} function given on page 79 of |
|
2067 Boolos's book. It is one of the two notions of integeral logarithmatic |
|
2068 operation on that page. The other is @{text "lo"}. |
|
2069 *} |
|
2070 fun lg :: "nat \<Rightarrow> nat \<Rightarrow> nat" |
|
2071 where |
|
2072 "lg x y = (if x > 1 \<and> y > 1 \<and> {u. lgR [x, y, u]} \<noteq> {} then |
|
2073 Max {u. lgR [x, y, u]} |
|
2074 else 0)" |
|
2075 |
|
2076 declare lg.simps[simp del] lgR.simps[simp del] |
|
2077 |
|
2078 text {* |
|
2079 @{text "rec_lg"} is the recursive function used to implement @{text "lg"}. |
|
2080 *} |
|
2081 definition rec_lg :: "recf" |
|
2082 where |
|
2083 "rec_lg = (let rec_lgR = Cn 3 rec_le |
|
2084 [Cn 3 rec_power [id 3 1, id 3 2], id 3 0] in |
|
2085 let conR1 = Cn 2 rec_conj [Cn 2 rec_less |
|
2086 [Cn 2 (constn 1) [id 2 0], id 2 0], |
|
2087 Cn 2 rec_less [Cn 2 (constn 1) |
|
2088 [id 2 0], id 2 1]] in |
|
2089 let conR2 = Cn 2 rec_not [conR1] in |
|
2090 Cn 2 rec_add [Cn 2 rec_mult |
|
2091 [conR1, Cn 2 (rec_maxr rec_lgR) |
|
2092 [id 2 0, id 2 1, id 2 0]], |
|
2093 Cn 2 rec_mult [conR2, Cn 2 (constn 0) |
|
2094 [id 2 0]]])" |
|
2095 |
|
2096 lemma lg_maxr: "\<lbrakk>Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow> |
|
2097 rec_exec rec_lg [x, y] = Maxr lgR [x, y] x" |
|
2098 proof(simp add: rec_exec.simps rec_lg_def Let_def) |
|
2099 assume h: "Suc 0 < x" "Suc 0 < y" |
|
2100 let ?rR = "(Cn 3 rec_le [Cn 3 rec_power |
|
2101 [recf.id 3 (Suc 0), recf.id 3 2], recf.id 3 0])" |
|
2102 have "rec_exec (rec_maxr ?rR) ([x, y] @ [x]) |
|
2103 = Maxr ((\<lambda> args. 0 < rec_exec ?rR args)) [x, y] x" |
|
2104 proof(rule Maxr_lemma) |
|
2105 show "primerec (Cn 3 rec_le [Cn 3 rec_power |
|
2106 [recf.id 3 (Suc 0), recf.id 3 2], recf.id 3 0]) (Suc (length [x, y]))" |
|
2107 apply(auto simp: numeral_3_eq_3)+ |
|
2108 done |
|
2109 qed |
|
2110 moreover have "Maxr lgR [x, y] x = Maxr ((\<lambda> args. 0 < rec_exec ?rR args)) [x, y] x" |
|
2111 apply(simp add: rec_exec.simps power_lemma) |
|
2112 apply(simp add: Maxr.simps lgR.simps) |
|
2113 done |
|
2114 ultimately show "rec_exec (rec_maxr ?rR) [x, y, x] = Maxr lgR [x, y] x" |
|
2115 by simp |
|
2116 qed |
|
2117 |
|
2118 lemma [simp]: "\<lbrakk>Suc 0 < y; lgR [x, y, xa]\<rbrakk> \<Longrightarrow> xa \<le> x" |
|
2119 apply(simp add: lgR.simps) |
|
2120 apply(subgoal_tac "y^xa > xa", simp) |
|
2121 apply(erule x_less_exp) |
|
2122 done |
|
2123 |
|
2124 lemma [simp]: "\<lbrakk>Suc 0 < x; Suc 0 < y; lgR [x, y, xa]\<rbrakk> \<Longrightarrow> |
|
2125 {u. lgR [x, y, u]} = {ya. ya \<le> x \<and> lgR [x, y, ya]}" |
|
2126 apply(rule_tac Collect_cong, auto) |
|
2127 done |
|
2128 |
|
2129 lemma maxr_lg: "\<lbrakk>Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow> Maxr lgR [x, y] x = lg x y" |
|
2130 apply(simp add: lg.simps Maxr.simps, auto) |
|
2131 apply(erule_tac x = xa in allE, simp) |
|
2132 done |
|
2133 |
|
2134 lemma lg_lemma': "\<lbrakk>Suc 0 < x; Suc 0 < y\<rbrakk> \<Longrightarrow> rec_exec rec_lg [x, y] = lg x y" |
|
2135 apply(simp add: maxr_lg lg_maxr) |
|
2136 done |
|
2137 |
|
2138 lemma lg_lemma'': "\<not> Suc 0 < x \<Longrightarrow> rec_exec rec_lg [x, y] = lg x y" |
|
2139 apply(simp add: rec_exec.simps rec_lg_def Let_def lg.simps) |
|
2140 done |
|
2141 |
|
2142 lemma lg_lemma''': "\<not> Suc 0 < y \<Longrightarrow> rec_exec rec_lg [x, y] = lg x y" |
|
2143 apply(simp add: rec_exec.simps rec_lg_def Let_def lg.simps) |
|
2144 done |
|
2145 |
|
2146 text {* |
|
2147 The correctness of @{text "rec_lg"}. |
|
2148 *} |
|
2149 lemma lg_lemma: "rec_exec rec_lg [x, y] = lg x y" |
|
2150 apply(case_tac "Suc 0 < x \<and> Suc 0 < y", auto simp: |
|
2151 lg_lemma' lg_lemma'' lg_lemma''') |
|
2152 done |
|
2153 |
|
2154 text {* |
|
2155 @{text "Entry sr i"} returns the @{text "i"}-th entry of a list of natural |
|
2156 numbers encoded by number @{text "sr"} using Godel's coding. |
|
2157 *} |
|
2158 fun Entry :: "nat \<Rightarrow> nat \<Rightarrow> nat" |
|
2159 where |
|
2160 "Entry sr i = lo sr (Pi (Suc i))" |
|
2161 |
|
2162 text {* |
|
2163 @{text "rec_entry"} is the recursive function used to implement |
|
2164 @{text "Entry"}. |
|
2165 *} |
|
2166 definition rec_entry:: "recf" |
|
2167 where |
|
2168 "rec_entry = Cn 2 rec_lo [id 2 0, Cn 2 rec_pi [Cn 2 s [id 2 1]]]" |
|
2169 |
|
2170 declare Pi.simps[simp del] |
|
2171 |
|
2172 text {* |
|
2173 The correctness of @{text "rec_entry"}. |
|
2174 *} |
|
2175 lemma entry_lemma: "rec_exec rec_entry [str, i] = Entry str i" |
|
2176 by(simp add: rec_entry_def rec_exec.simps lo_lemma pi_lemma) |
|
2177 |
|
2178 section {* The construction of @{text "F"} *} |
|
2179 |
|
2180 text {* |
|
2181 Using the auxilliary functions obtained in last section, |
|
2182 we are going to contruct the function @{text "F"}, |
|
2183 which is an interpreter of Turing Machines. |
|
2184 *} |
|
2185 |
|
2186 fun listsum2 :: "nat list \<Rightarrow> nat \<Rightarrow> nat" |
|
2187 where |
|
2188 "listsum2 xs 0 = 0" |
|
2189 | "listsum2 xs (Suc n) = listsum2 xs n + xs ! n" |
|
2190 |
|
2191 fun rec_listsum2 :: "nat \<Rightarrow> nat \<Rightarrow> recf" |
|
2192 where |
|
2193 "rec_listsum2 vl 0 = Cn vl z [id vl 0]" |
|
2194 | "rec_listsum2 vl (Suc n) = Cn vl rec_add |
|
2195 [rec_listsum2 vl n, id vl (n)]" |
|
2196 |
|
2197 declare listsum2.simps[simp del] rec_listsum2.simps[simp del] |
|
2198 |
|
2199 lemma listsum2_lemma: "\<lbrakk>length xs = vl; n \<le> vl\<rbrakk> \<Longrightarrow> |
|
2200 rec_exec (rec_listsum2 vl n) xs = listsum2 xs n" |
|
2201 apply(induct n, simp_all) |
|
2202 apply(simp_all add: rec_exec.simps rec_listsum2.simps listsum2.simps) |
|
2203 done |
|
2204 |
|
2205 fun strt' :: "nat list \<Rightarrow> nat \<Rightarrow> nat" |
|
2206 where |
|
2207 "strt' xs 0 = 0" |
|
2208 | "strt' xs (Suc n) = (let dbound = listsum2 xs n + n in |
|
2209 strt' xs n + (2^(xs ! n + dbound) - 2^dbound))" |
|
2210 |
|
2211 fun rec_strt' :: "nat \<Rightarrow> nat \<Rightarrow> recf" |
|
2212 where |
|
2213 "rec_strt' vl 0 = Cn vl z [id vl 0]" |
|
2214 | "rec_strt' vl (Suc n) = (let rec_dbound = |
|
2215 Cn vl rec_add [rec_listsum2 vl n, Cn vl (constn n) [id vl 0]] |
|
2216 in Cn vl rec_add [rec_strt' vl n, Cn vl rec_minus |
|
2217 [Cn vl rec_power [Cn vl (constn 2) [id vl 0], Cn vl rec_add |
|
2218 [id vl (n), rec_dbound]], |
|
2219 Cn vl rec_power [Cn vl (constn 2) [id vl 0], rec_dbound]]])" |
|
2220 |
|
2221 declare strt'.simps[simp del] rec_strt'.simps[simp del] |
|
2222 |
|
2223 lemma strt'_lemma: "\<lbrakk>length xs = vl; n \<le> vl\<rbrakk> \<Longrightarrow> |
|
2224 rec_exec (rec_strt' vl n) xs = strt' xs n" |
|
2225 apply(induct n) |
|
2226 apply(simp_all add: rec_exec.simps rec_strt'.simps strt'.simps |
|
2227 Let_def power_lemma listsum2_lemma) |
|
2228 done |
|
2229 |
|
2230 text {* |
|
2231 @{text "strt"} corresponds to the @{text "strt"} function on page 90 of B book, but |
|
2232 this definition generalises the original one to deal with multiple input arguments. |
|
2233 *} |
|
2234 fun strt :: "nat list \<Rightarrow> nat" |
|
2235 where |
|
2236 "strt xs = (let ys = map Suc xs in |
|
2237 strt' ys (length ys))" |
|
2238 |
|
2239 fun rec_map :: "recf \<Rightarrow> nat \<Rightarrow> recf list" |
|
2240 where |
|
2241 "rec_map rf vl = map (\<lambda> i. Cn vl rf [id vl (i)]) [0..<vl]" |
|
2242 |
|
2243 text {* |
|
2244 @{text "rec_strt"} is the recursive function used to implement @{text "strt"}. |
|
2245 *} |
|
2246 fun rec_strt :: "nat \<Rightarrow> recf" |
|
2247 where |
|
2248 "rec_strt vl = Cn vl (rec_strt' vl vl) (rec_map s vl)" |
|
2249 |
|
2250 lemma map_s_lemma: "length xs = vl \<Longrightarrow> |
|
2251 map ((\<lambda>a. rec_exec a xs) \<circ> (\<lambda>i. Cn vl s [recf.id vl i])) |
|
2252 [0..<vl] |
|
2253 = map Suc xs" |
|
2254 apply(induct vl arbitrary: xs, simp, auto simp: rec_exec.simps) |
|
2255 apply(subgoal_tac "\<exists> ys y. xs = ys @ [y]", auto) |
|
2256 proof - |
|
2257 fix ys y |
|
2258 assume ind: "\<And>xs. length xs = length (ys::nat list) \<Longrightarrow> |
|
2259 map ((\<lambda>a. rec_exec a xs) \<circ> (\<lambda>i. Cn (length ys) s |
|
2260 [recf.id (length ys) (i)])) [0..<length ys] = map Suc xs" |
|
2261 show |
|
2262 "map ((\<lambda>a. rec_exec a (ys @ [y])) \<circ> (\<lambda>i. Cn (Suc (length ys)) s |
|
2263 [recf.id (Suc (length ys)) (i)])) [0..<length ys] = map Suc ys" |
|
2264 proof - |
|
2265 have "map ((\<lambda>a. rec_exec a ys) \<circ> (\<lambda>i. Cn (length ys) s |
|
2266 [recf.id (length ys) (i)])) [0..<length ys] = map Suc ys" |
|
2267 apply(rule_tac ind, simp) |
|
2268 done |
|
2269 moreover have |
|
2270 "map ((\<lambda>a. rec_exec a (ys @ [y])) \<circ> (\<lambda>i. Cn (Suc (length ys)) s |
|
2271 [recf.id (Suc (length ys)) (i)])) [0..<length ys] |
|
2272 = map ((\<lambda>a. rec_exec a ys) \<circ> (\<lambda>i. Cn (length ys) s |
|
2273 [recf.id (length ys) (i)])) [0..<length ys]" |
|
2274 apply(rule_tac map_ext, auto simp: rec_exec.simps nth_append) |
|
2275 done |
|
2276 ultimately show "?thesis" |
|
2277 by simp |
|
2278 qed |
|
2279 next |
|
2280 fix vl xs |
|
2281 assume "length xs = Suc vl" |
|
2282 thus "\<exists>ys y. xs = ys @ [y]" |
|
2283 apply(rule_tac x = "butlast xs" in exI, rule_tac x = "last xs" in exI) |
|
2284 apply(subgoal_tac "xs \<noteq> []", auto) |
|
2285 done |
|
2286 qed |
|
2287 |
|
2288 text {* |
|
2289 The correctness of @{text "rec_strt"}. |
|
2290 *} |
|
2291 lemma strt_lemma: "length xs = vl \<Longrightarrow> |
|
2292 rec_exec (rec_strt vl) xs = strt xs" |
|
2293 apply(simp add: strt.simps rec_exec.simps strt'_lemma) |
|
2294 apply(subgoal_tac "(map ((\<lambda>a. rec_exec a xs) \<circ> (\<lambda>i. Cn vl s [recf.id vl (i)])) [0..<vl]) |
|
2295 = map Suc xs", auto) |
|
2296 apply(rule map_s_lemma, simp) |
|
2297 done |
|
2298 |
|
2299 text {* |
|
2300 The @{text "scan"} function on page 90 of B book. |
|
2301 *} |
|
2302 fun scan :: "nat \<Rightarrow> nat" |
|
2303 where |
|
2304 "scan r = r mod 2" |
|
2305 |
|
2306 text {* |
|
2307 @{text "rec_scan"} is the implemention of @{text "scan"}. |
|
2308 *} |
|
2309 definition rec_scan :: "recf" |
|
2310 where "rec_scan = Cn 1 rec_mod [id 1 0, constn 2]" |
|
2311 |
|
2312 text {* |
|
2313 The correctness of @{text "scan"}. |
|
2314 *} |
|
2315 lemma scan_lemma: "rec_exec rec_scan [r] = r mod 2" |
|
2316 by(simp add: rec_exec.simps rec_scan_def mod_lemma) |
|
2317 |
|
2318 fun newleft0 :: "nat list \<Rightarrow> nat" |
|
2319 where |
|
2320 "newleft0 [p, r] = p" |
|
2321 |
|
2322 definition rec_newleft0 :: "recf" |
|
2323 where |
|
2324 "rec_newleft0 = id 2 0" |
|
2325 |
|
2326 fun newrgt0 :: "nat list \<Rightarrow> nat" |
|
2327 where |
|
2328 "newrgt0 [p, r] = r - scan r" |
|
2329 |
|
2330 definition rec_newrgt0 :: "recf" |
|
2331 where |
|
2332 "rec_newrgt0 = Cn 2 rec_minus [id 2 1, Cn 2 rec_scan [id 2 1]]" |
|
2333 |
|
2334 (*newleft1, newrgt1: left rgt number after execute on step*) |
|
2335 fun newleft1 :: "nat list \<Rightarrow> nat" |
|
2336 where |
|
2337 "newleft1 [p, r] = p" |
|
2338 |
|
2339 definition rec_newleft1 :: "recf" |
|
2340 where |
|
2341 "rec_newleft1 = id 2 0" |
|
2342 |
|
2343 fun newrgt1 :: "nat list \<Rightarrow> nat" |
|
2344 where |
|
2345 "newrgt1 [p, r] = r + 1 - scan r" |
|
2346 |
|
2347 definition rec_newrgt1 :: "recf" |
|
2348 where |
|
2349 "rec_newrgt1 = |
|
2350 Cn 2 rec_minus [Cn 2 rec_add [id 2 1, Cn 2 (constn 1) [id 2 0]], |
|
2351 Cn 2 rec_scan [id 2 1]]" |
|
2352 |
|
2353 fun newleft2 :: "nat list \<Rightarrow> nat" |
|
2354 where |
|
2355 "newleft2 [p, r] = p div 2" |
|
2356 |
|
2357 definition rec_newleft2 :: "recf" |
|
2358 where |
|
2359 "rec_newleft2 = Cn 2 rec_quo [id 2 0, Cn 2 (constn 2) [id 2 0]]" |
|
2360 |
|
2361 fun newrgt2 :: "nat list \<Rightarrow> nat" |
|
2362 where |
|
2363 "newrgt2 [p, r] = 2 * r + p mod 2" |
|
2364 |
|
2365 definition rec_newrgt2 :: "recf" |
|
2366 where |
|
2367 "rec_newrgt2 = |
|
2368 Cn 2 rec_add [Cn 2 rec_mult [Cn 2 (constn 2) [id 2 0], id 2 1], |
|
2369 Cn 2 rec_mod [id 2 0, Cn 2 (constn 2) [id 2 0]]]" |
|
2370 |
|
2371 fun newleft3 :: "nat list \<Rightarrow> nat" |
|
2372 where |
|
2373 "newleft3 [p, r] = 2 * p + r mod 2" |
|
2374 |
|
2375 definition rec_newleft3 :: "recf" |
|
2376 where |
|
2377 "rec_newleft3 = |
|
2378 Cn 2 rec_add [Cn 2 rec_mult [Cn 2 (constn 2) [id 2 0], id 2 0], |
|
2379 Cn 2 rec_mod [id 2 1, Cn 2 (constn 2) [id 2 0]]]" |
|
2380 |
|
2381 fun newrgt3 :: "nat list \<Rightarrow> nat" |
|
2382 where |
|
2383 "newrgt3 [p, r] = r div 2" |
|
2384 |
|
2385 definition rec_newrgt3 :: "recf" |
|
2386 where |
|
2387 "rec_newrgt3 = Cn 2 rec_quo [id 2 1, Cn 2 (constn 2) [id 2 0]]" |
|
2388 |
|
2389 text {* |
|
2390 The @{text "new_left"} function on page 91 of B book. |
|
2391 *} |
|
2392 fun newleft :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat" |
|
2393 where |
|
2394 "newleft p r a = (if a = 0 \<or> a = 1 then newleft0 [p, r] |
|
2395 else if a = 2 then newleft2 [p, r] |
|
2396 else if a = 3 then newleft3 [p, r] |
|
2397 else p)" |
|
2398 |
|
2399 text {* |
|
2400 @{text "rec_newleft"} is the recursive function used to |
|
2401 implement @{text "newleft"}. |
|
2402 *} |
|
2403 definition rec_newleft :: "recf" |
|
2404 where |
|
2405 "rec_newleft = |
|
2406 (let g0 = |
|
2407 Cn 3 rec_newleft0 [id 3 0, id 3 1] in |
|
2408 let g1 = Cn 3 rec_newleft2 [id 3 0, id 3 1] in |
|
2409 let g2 = Cn 3 rec_newleft3 [id 3 0, id 3 1] in |
|
2410 let g3 = id 3 0 in |
|
2411 let r0 = Cn 3 rec_disj |
|
2412 [Cn 3 rec_eq [id 3 2, Cn 3 (constn 0) [id 3 0]], |
|
2413 Cn 3 rec_eq [id 3 2, Cn 3 (constn 1) [id 3 0]]] in |
|
2414 let r1 = Cn 3 rec_eq [id 3 2, Cn 3 (constn 2) [id 3 0]] in |
|
2415 let r2 = Cn 3 rec_eq [id 3 2, Cn 3 (constn 3) [id 3 0]] in |
|
2416 let r3 = Cn 3 rec_less [Cn 3 (constn 3) [id 3 0], id 3 2] in |
|
2417 let gs = [g0, g1, g2, g3] in |
|
2418 let rs = [r0, r1, r2, r3] in |
|
2419 rec_embranch (zip gs rs))" |
|
2420 |
|
2421 declare newleft.simps[simp del] |
|
2422 |
|
2423 |
|
2424 lemma Suc_Suc_Suc_Suc_induct: |
|
2425 "\<lbrakk>i < Suc (Suc (Suc (Suc 0))); i = 0 \<Longrightarrow> P i; |
|
2426 i = 1 \<Longrightarrow> P i; i =2 \<Longrightarrow> P i; |
|
2427 i =3 \<Longrightarrow> P i\<rbrakk> \<Longrightarrow> P i" |
|
2428 apply(case_tac i, simp, case_tac nat, simp, |
|
2429 case_tac nata, simp, case_tac natb, simp, simp) |
|
2430 done |
|
2431 |
|
2432 declare quo_lemma2[simp] mod_lemma[simp] |
|
2433 |
|
2434 text {* |
|
2435 The correctness of @{text "rec_newleft"}. |
|
2436 *} |
|
2437 lemma newleft_lemma: |
|
2438 "rec_exec rec_newleft [p, r, a] = newleft p r a" |
|
2439 proof(simp only: rec_newleft_def Let_def) |
|
2440 let ?rgs = "[Cn 3 rec_newleft0 [recf.id 3 0, recf.id 3 1], Cn 3 rec_newleft2 |
|
2441 [recf.id 3 0, recf.id 3 1], Cn 3 rec_newleft3 [recf.id 3 0, recf.id 3 1], recf.id 3 0]" |
|
2442 let ?rrs = |
|
2443 "[Cn 3 rec_disj [Cn 3 rec_eq [recf.id 3 2, Cn 3 (constn 0) |
|
2444 [recf.id 3 0]], Cn 3 rec_eq [recf.id 3 2, Cn 3 (constn 1) [recf.id 3 0]]], |
|
2445 Cn 3 rec_eq [recf.id 3 2, Cn 3 (constn 2) [recf.id 3 0]], |
|
2446 Cn 3 rec_eq [recf.id 3 2, Cn 3 (constn 3) [recf.id 3 0]], |
|
2447 Cn 3 rec_less [Cn 3 (constn 3) [recf.id 3 0], recf.id 3 2]]" |
|
2448 thm embranch_lemma |
|
2449 have k1: "rec_exec (rec_embranch (zip ?rgs ?rrs)) [p, r, a] |
|
2450 = Embranch (zip (map rec_exec ?rgs) (map (\<lambda>r args. 0 < rec_exec r args) ?rrs)) [p, r, a]" |
|
2451 apply(rule_tac embranch_lemma ) |
|
2452 apply(auto simp: numeral_3_eq_3 numeral_2_eq_2 rec_newleft0_def |
|
2453 rec_newleft1_def rec_newleft2_def rec_newleft3_def)+ |
|
2454 apply(case_tac "a = 0 \<or> a = 1", rule_tac x = 0 in exI) |
|
2455 prefer 2 |
|
2456 apply(case_tac "a = 2", rule_tac x = "Suc 0" in exI) |
|
2457 prefer 2 |
|
2458 apply(case_tac "a = 3", rule_tac x = "2" in exI) |
|
2459 prefer 2 |
|
2460 apply(case_tac "a > 3", rule_tac x = "3" in exI, auto) |
|
2461 apply(auto simp: rec_exec.simps) |
|
2462 apply(erule_tac [!] Suc_Suc_Suc_Suc_induct, auto simp: rec_exec.simps) |
|
2463 done(* |
|
2464 have "Embranch (zip (map rec_exec ?rgs) (map (\<lambda>r args. 0 < rec_exec r args) ?rrs)) [p, r, a] |
|
2465 = Embranch (zip ?gs ?rs) [p, r, a]" |
|
2466 apply(simp add)*) |
|
2467 have k2: "Embranch (zip (map rec_exec ?rgs) (map (\<lambda>r args. 0 < rec_exec r args) ?rrs)) [p, r, a] = newleft p r a" |
|
2468 apply(simp add: Embranch.simps) |
|
2469 apply(simp add: rec_exec.simps) |
|
2470 apply(auto simp: newleft.simps rec_newleft0_def rec_exec.simps |
|
2471 rec_newleft1_def rec_newleft2_def rec_newleft3_def) |
|
2472 done |
|
2473 from k1 and k2 show |
|
2474 "rec_exec (rec_embranch (zip ?rgs ?rrs)) [p, r, a] = newleft p r a" |
|
2475 by simp |
|
2476 qed |
|
2477 |
|
2478 text {* |
|
2479 The @{text "newrght"} function is one similar to @{text "newleft"}, but used to |
|
2480 compute the right number. |
|
2481 *} |
|
2482 fun newrght :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat" |
|
2483 where |
|
2484 "newrght p r a = (if a = 0 then newrgt0 [p, r] |
|
2485 else if a = 1 then newrgt1 [p, r] |
|
2486 else if a = 2 then newrgt2 [p, r] |
|
2487 else if a = 3 then newrgt3 [p, r] |
|
2488 else r)" |
|
2489 |
|
2490 text {* |
|
2491 @{text "rec_newrght"} is the recursive function used to implement |
|
2492 @{text "newrgth"}. |
|
2493 *} |
|
2494 definition rec_newrght :: "recf" |
|
2495 where |
|
2496 "rec_newrght = |
|
2497 (let g0 = Cn 3 rec_newrgt0 [id 3 0, id 3 1] in |
|
2498 let g1 = Cn 3 rec_newrgt1 [id 3 0, id 3 1] in |
|
2499 let g2 = Cn 3 rec_newrgt2 [id 3 0, id 3 1] in |
|
2500 let g3 = Cn 3 rec_newrgt3 [id 3 0, id 3 1] in |
|
2501 let g4 = id 3 1 in |
|
2502 let r0 = Cn 3 rec_eq [id 3 2, Cn 3 (constn 0) [id 3 0]] in |
|
2503 let r1 = Cn 3 rec_eq [id 3 2, Cn 3 (constn 1) [id 3 0]] in |
|
2504 let r2 = Cn 3 rec_eq [id 3 2, Cn 3 (constn 2) [id 3 0]] in |
|
2505 let r3 = Cn 3 rec_eq [id 3 2, Cn 3 (constn 3) [id 3 0]] in |
|
2506 let r4 = Cn 3 rec_less [Cn 3 (constn 3) [id 3 0], id 3 2] in |
|
2507 let gs = [g0, g1, g2, g3, g4] in |
|
2508 let rs = [r0, r1, r2, r3, r4] in |
|
2509 rec_embranch (zip gs rs))" |
|
2510 declare newrght.simps[simp del] |
|
2511 |
|
2512 lemma numeral_4_eq_4: "4 = Suc 3" |
|
2513 by auto |
|
2514 |
|
2515 lemma Suc_5_induct: |
|
2516 "\<lbrakk>i < Suc (Suc (Suc (Suc (Suc 0)))); i = 0 \<Longrightarrow> P 0; |
|
2517 i = 1 \<Longrightarrow> P 1; i = 2 \<Longrightarrow> P 2; i = 3 \<Longrightarrow> P 3; i = 4 \<Longrightarrow> P 4\<rbrakk> \<Longrightarrow> P i" |
|
2518 apply(case_tac i, auto) |
|
2519 apply(case_tac nat, auto) |
|
2520 apply(case_tac nata, auto simp: numeral_2_eq_2) |
|
2521 apply(case_tac nat, auto simp: numeral_3_eq_3 numeral_4_eq_4) |
|
2522 done |
|
2523 |
|
2524 lemma [intro]: "primerec rec_scan (Suc 0)" |
|
2525 apply(auto simp: rec_scan_def, auto) |
|
2526 done |
|
2527 |
|
2528 text {* |
|
2529 The correctness of @{text "rec_newrght"}. |
|
2530 *} |
|
2531 lemma newrght_lemma: "rec_exec rec_newrght [p, r, a] = newrght p r a" |
|
2532 proof(simp only: rec_newrght_def Let_def) |
|
2533 let ?gs' = "[newrgt0, newrgt1, newrgt2, newrgt3, \<lambda> zs. zs ! 1]" |
|
2534 let ?r0 = "\<lambda> zs. zs ! 2 = 0" |
|
2535 let ?r1 = "\<lambda> zs. zs ! 2 = 1" |
|
2536 let ?r2 = "\<lambda> zs. zs ! 2 = 2" |
|
2537 let ?r3 = "\<lambda> zs. zs ! 2 = 3" |
|
2538 let ?r4 = "\<lambda> zs. zs ! 2 > 3" |
|
2539 let ?gs = "map (\<lambda> g. (\<lambda> zs. g [zs ! 0, zs ! 1])) ?gs'" |
|
2540 let ?rs = "[?r0, ?r1, ?r2, ?r3, ?r4]" |
|
2541 let ?rgs = |
|
2542 "[Cn 3 rec_newrgt0 [recf.id 3 0, recf.id 3 1], |
|
2543 Cn 3 rec_newrgt1 [recf.id 3 0, recf.id 3 1], |
|
2544 Cn 3 rec_newrgt2 [recf.id 3 0, recf.id 3 1], |
|
2545 Cn 3 rec_newrgt3 [recf.id 3 0, recf.id 3 1], recf.id 3 1]" |
|
2546 let ?rrs = |
|
2547 "[Cn 3 rec_eq [recf.id 3 2, Cn 3 (constn 0) [recf.id 3 0]], Cn 3 rec_eq [recf.id 3 2, |
|
2548 Cn 3 (constn 1) [recf.id 3 0]], Cn 3 rec_eq [recf.id 3 2, Cn 3 (constn 2) [recf.id 3 0]], |
|
2549 Cn 3 rec_eq [recf.id 3 2, Cn 3 (constn 3) [recf.id 3 0]], |
|
2550 Cn 3 rec_less [Cn 3 (constn 3) [recf.id 3 0], recf.id 3 2]]" |
|
2551 |
|
2552 have k1: "rec_exec (rec_embranch (zip ?rgs ?rrs)) [p, r, a] |
|
2553 = Embranch (zip (map rec_exec ?rgs) (map (\<lambda>r args. 0 < rec_exec r args) ?rrs)) [p, r, a]" |
|
2554 apply(rule_tac embranch_lemma) |
|
2555 apply(auto simp: numeral_3_eq_3 numeral_2_eq_2 rec_newrgt0_def |
|
2556 rec_newrgt1_def rec_newrgt2_def rec_newrgt3_def)+ |
|
2557 apply(case_tac "a = 0", rule_tac x = 0 in exI) |
|
2558 prefer 2 |
|
2559 apply(case_tac "a = 1", rule_tac x = "Suc 0" in exI) |
|
2560 prefer 2 |
|
2561 apply(case_tac "a = 2", rule_tac x = "2" in exI) |
|
2562 prefer 2 |
|
2563 apply(case_tac "a = 3", rule_tac x = "3" in exI) |
|
2564 prefer 2 |
|
2565 apply(case_tac "a > 3", rule_tac x = "4" in exI, auto simp: rec_exec.simps) |
|
2566 apply(erule_tac [!] Suc_5_induct, auto simp: rec_exec.simps) |
|
2567 done |
|
2568 have k2: "Embranch (zip (map rec_exec ?rgs) |
|
2569 (map (\<lambda>r args. 0 < rec_exec r args) ?rrs)) [p, r, a] = newrght p r a" |
|
2570 apply(auto simp:Embranch.simps rec_exec.simps) |
|
2571 apply(auto simp: newrght.simps rec_newrgt3_def rec_newrgt2_def |
|
2572 rec_newrgt1_def rec_newrgt0_def rec_exec.simps |
|
2573 scan_lemma) |
|
2574 done |
|
2575 from k1 and k2 show |
|
2576 "rec_exec (rec_embranch (zip ?rgs ?rrs)) [p, r, a] = |
|
2577 newrght p r a" by simp |
|
2578 qed |
|
2579 |
|
2580 declare Entry.simps[simp del] |
|
2581 |
|
2582 text {* |
|
2583 The @{text "actn"} function given on page 92 of B book, which is used to |
|
2584 fetch Turing Machine intructions. |
|
2585 In @{text "actn m q r"}, @{text "m"} is the Godel coding of a Turing Machine, |
|
2586 @{text "q"} is the current state of Turing Machine, @{text "r"} is the |
|
2587 right number of Turing Machine tape. |
|
2588 *} |
|
2589 fun actn :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat" |
|
2590 where |
|
2591 "actn m q r = (if q \<noteq> 0 then Entry m (4*(q - 1) + 2 * scan r) |
|
2592 else 4)" |
|
2593 |
|
2594 text {* |
|
2595 @{text "rec_actn"} is the recursive function used to implement @{text "actn"} |
|
2596 *} |
|
2597 definition rec_actn :: "recf" |
|
2598 where |
|
2599 "rec_actn = |
|
2600 Cn 3 rec_add [Cn 3 rec_mult |
|
2601 [Cn 3 rec_entry [id 3 0, Cn 3 rec_add [Cn 3 rec_mult |
|
2602 [Cn 3 (constn 4) [id 3 0], |
|
2603 Cn 3 rec_minus [id 3 1, Cn 3 (constn 1) [id 3 0]]], |
|
2604 Cn 3 rec_mult [Cn 3 (constn 2) [id 3 0], |
|
2605 Cn 3 rec_scan [id 3 2]]]], |
|
2606 Cn 3 rec_noteq [id 3 1, Cn 3 (constn 0) [id 3 0]]], |
|
2607 Cn 3 rec_mult [Cn 3 (constn 4) [id 3 0], |
|
2608 Cn 3 rec_eq [id 3 1, Cn 3 (constn 0) [id 3 0]]]] " |
|
2609 |
|
2610 text {* |
|
2611 The correctness of @{text "actn"}. |
|
2612 *} |
|
2613 lemma actn_lemma: "rec_exec rec_actn [m, q, r] = actn m q r" |
|
2614 by(auto simp: rec_actn_def rec_exec.simps entry_lemma scan_lemma) |
|
2615 |
|
2616 (* Stop point *) |
|
2617 |
|
2618 fun newstat :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat" |
|
2619 where |
|
2620 "newstat m q r = (if q \<noteq> 0 then Entry m (4*(q - 1) + 2*scan r + 1) |
|
2621 else 0)" |
|
2622 |
|
2623 definition rec_newstat :: "recf" |
|
2624 where |
|
2625 "rec_newstat = Cn 3 rec_add |
|
2626 [Cn 3 rec_mult [Cn 3 rec_entry [id 3 0, |
|
2627 Cn 3 rec_add [Cn 3 rec_mult [Cn 3 (constn 4) [id 3 0], |
|
2628 Cn 3 rec_minus [id 3 1, Cn 3 (constn 1) [id 3 0]]], |
|
2629 Cn 3 rec_add [Cn 3 rec_mult [Cn 3 (constn 2) [id 3 0], |
|
2630 Cn 3 rec_scan [id 3 2]], Cn 3 (constn 1) [id 3 0]]]], |
|
2631 Cn 3 rec_noteq [id 3 1, Cn 3 (constn 0) [id 3 0]]], |
|
2632 Cn 3 rec_mult [Cn 3 (constn 0) [id 3 0], |
|
2633 Cn 3 rec_eq [id 3 1, Cn 3 (constn 0) [id 3 0]]]] " |
|
2634 |
|
2635 lemma newstat_lemma: "rec_exec rec_newstat [m, q, r] = newstat m q r" |
|
2636 by(auto simp: rec_exec.simps entry_lemma scan_lemma rec_newstat_def) |
|
2637 |
|
2638 declare newstat.simps[simp del] actn.simps[simp del] |
|
2639 |
|
2640 text{*code the configuration*} |
|
2641 |
|
2642 fun trpl :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat" |
|
2643 where |
|
2644 "trpl p q r = (Pi 0)^p * (Pi 1)^q * (Pi 2)^r" |
|
2645 |
|
2646 definition rec_trpl :: "recf" |
|
2647 where |
|
2648 "rec_trpl = Cn 3 rec_mult [Cn 3 rec_mult |
|
2649 [Cn 3 rec_power [Cn 3 (constn (Pi 0)) [id 3 0], id 3 0], |
|
2650 Cn 3 rec_power [Cn 3 (constn (Pi 1)) [id 3 0], id 3 1]], |
|
2651 Cn 3 rec_power [Cn 3 (constn (Pi 2)) [id 3 0], id 3 2]]" |
|
2652 declare trpl.simps[simp del] |
|
2653 lemma trpl_lemma: "rec_exec rec_trpl [p, q, r] = trpl p q r" |
|
2654 by(auto simp: rec_trpl_def rec_exec.simps power_lemma trpl.simps) |
|
2655 |
|
2656 text{*left, stat, rght: decode func*} |
|
2657 fun left :: "nat \<Rightarrow> nat" |
|
2658 where |
|
2659 "left c = lo c (Pi 0)" |
|
2660 |
|
2661 fun stat :: "nat \<Rightarrow> nat" |
|
2662 where |
|
2663 "stat c = lo c (Pi 1)" |
|
2664 |
|
2665 fun rght :: "nat \<Rightarrow> nat" |
|
2666 where |
|
2667 "rght c = lo c (Pi 2)" |
|
2668 |
|
2669 thm Prime.simps |
|
2670 |
|
2671 fun inpt :: "nat \<Rightarrow> nat list \<Rightarrow> nat" |
|
2672 where |
|
2673 "inpt m xs = trpl 0 1 (strt xs)" |
|
2674 |
|
2675 fun newconf :: "nat \<Rightarrow> nat \<Rightarrow> nat" |
|
2676 where |
|
2677 "newconf m c = trpl (newleft (left c) (rght c) |
|
2678 (actn m (stat c) (rght c))) |
|
2679 (newstat m (stat c) (rght c)) |
|
2680 (newrght (left c) (rght c) |
|
2681 (actn m (stat c) (rght c)))" |
|
2682 |
|
2683 declare left.simps[simp del] stat.simps[simp del] rght.simps[simp del] |
|
2684 inpt.simps[simp del] newconf.simps[simp del] |
|
2685 |
|
2686 definition rec_left :: "recf" |
|
2687 where |
|
2688 "rec_left = Cn 1 rec_lo [id 1 0, constn (Pi 0)]" |
|
2689 |
|
2690 definition rec_right :: "recf" |
|
2691 where |
|
2692 "rec_right = Cn 1 rec_lo [id 1 0, constn (Pi 2)]" |
|
2693 |
|
2694 definition rec_stat :: "recf" |
|
2695 where |
|
2696 "rec_stat = Cn 1 rec_lo [id 1 0, constn (Pi 1)]" |
|
2697 |
|
2698 definition rec_inpt :: "nat \<Rightarrow> recf" |
|
2699 where |
|
2700 "rec_inpt vl = Cn vl rec_trpl |
|
2701 [Cn vl (constn 0) [id vl 0], |
|
2702 Cn vl (constn 1) [id vl 0], |
|
2703 Cn vl (rec_strt (vl - 1)) |
|
2704 (map (\<lambda> i. id vl (i)) [1..<vl])]" |
|
2705 |
|
2706 lemma left_lemma: "rec_exec rec_left [c] = left c" |
|
2707 by(simp add: rec_exec.simps rec_left_def left.simps lo_lemma) |
|
2708 |
|
2709 lemma right_lemma: "rec_exec rec_right [c] = rght c" |
|
2710 by(simp add: rec_exec.simps rec_right_def rght.simps lo_lemma) |
|
2711 |
|
2712 lemma stat_lemma: "rec_exec rec_stat [c] = stat c" |
|
2713 by(simp add: rec_exec.simps rec_stat_def stat.simps lo_lemma) |
|
2714 |
|
2715 declare rec_strt.simps[simp del] strt.simps[simp del] |
|
2716 |
|
2717 lemma map_cons_eq: |
|
2718 "(map ((\<lambda>a. rec_exec a (m # xs)) \<circ> |
|
2719 (\<lambda>i. recf.id (Suc (length xs)) (i))) |
|
2720 [Suc 0..<Suc (length xs)]) |
|
2721 = map (\<lambda> i. xs ! (i - 1)) [Suc 0..<Suc (length xs)]" |
|
2722 apply(rule map_ext, auto) |
|
2723 apply(auto simp: rec_exec.simps nth_append nth_Cons split: nat.split) |
|
2724 done |
|
2725 |
|
2726 lemma list_map_eq: |
|
2727 "vl = length (xs::nat list) \<Longrightarrow> map (\<lambda> i. xs ! (i - 1)) |
|
2728 [Suc 0..<Suc vl] = xs" |
|
2729 apply(induct vl arbitrary: xs, simp) |
|
2730 apply(subgoal_tac "\<exists> ys y. xs = ys @ [y]", auto) |
|
2731 proof - |
|
2732 fix ys y |
|
2733 assume ind: |
|
2734 "\<And>xs. length (ys::nat list) = length (xs::nat list) \<Longrightarrow> |
|
2735 map (\<lambda>i. xs ! (i - Suc 0)) [Suc 0..<length xs] @ |
|
2736 [xs ! (length xs - Suc 0)] = xs" |
|
2737 and h: "Suc 0 \<le> length (ys::nat list)" |
|
2738 have "map (\<lambda>i. ys ! (i - Suc 0)) [Suc 0..<length ys] @ |
|
2739 [ys ! (length ys - Suc 0)] = ys" |
|
2740 apply(rule_tac ind, simp) |
|
2741 done |
|
2742 moreover have |
|
2743 "map (\<lambda>i. (ys @ [y]) ! (i - Suc 0)) [Suc 0..<length ys] |
|
2744 = map (\<lambda>i. ys ! (i - Suc 0)) [Suc 0..<length ys]" |
|
2745 apply(rule map_ext) |
|
2746 using h |
|
2747 apply(auto simp: nth_append) |
|
2748 done |
|
2749 ultimately show "map (\<lambda>i. (ys @ [y]) ! (i - Suc 0)) |
|
2750 [Suc 0..<length ys] @ [(ys @ [y]) ! (length ys - Suc 0)] = ys" |
|
2751 apply(simp del: map_eq_conv add: nth_append, auto) |
|
2752 using h |
|
2753 apply(simp) |
|
2754 done |
|
2755 next |
|
2756 fix vl xs |
|
2757 assume "Suc vl = length (xs::nat list)" |
|
2758 thus "\<exists>ys y. xs = ys @ [y]" |
|
2759 apply(rule_tac x = "butlast xs" in exI, |
|
2760 rule_tac x = "last xs" in exI) |
|
2761 apply(case_tac "xs \<noteq> []", auto) |
|
2762 done |
|
2763 qed |
|
2764 |
|
2765 lemma [elim]: |
|
2766 "Suc 0 \<le> length xs \<Longrightarrow> |
|
2767 (map ((\<lambda>a. rec_exec a (m # xs)) \<circ> |
|
2768 (\<lambda>i. recf.id (Suc (length xs)) (i))) |
|
2769 [Suc 0..<length xs] @ [(m # xs) ! length xs]) = xs" |
|
2770 using map_cons_eq[of m xs] |
|
2771 apply(simp del: map_eq_conv add: rec_exec.simps) |
|
2772 using list_map_eq[of "length xs" xs] |
|
2773 apply(simp) |
|
2774 done |
|
2775 |
|
2776 |
|
2777 lemma inpt_lemma: |
|
2778 "\<lbrakk>Suc (length xs) = vl\<rbrakk> \<Longrightarrow> |
|
2779 rec_exec (rec_inpt vl) (m # xs) = inpt m xs" |
|
2780 apply(auto simp: rec_exec.simps rec_inpt_def |
|
2781 trpl_lemma inpt.simps strt_lemma) |
|
2782 apply(subgoal_tac |
|
2783 "(map ((\<lambda>a. rec_exec a (m # xs)) \<circ> |
|
2784 (\<lambda>i. recf.id (Suc (length xs)) (i))) |
|
2785 [Suc 0..<length xs] @ [(m # xs) ! length xs]) = xs", simp) |
|
2786 apply(auto, case_tac xs, auto) |
|
2787 done |
|
2788 |
|
2789 definition rec_newconf:: "recf" |
|
2790 where |
|
2791 "rec_newconf = |
|
2792 Cn 2 rec_trpl |
|
2793 [Cn 2 rec_newleft [Cn 2 rec_left [id 2 1], |
|
2794 Cn 2 rec_right [id 2 1], |
|
2795 Cn 2 rec_actn [id 2 0, |
|
2796 Cn 2 rec_stat [id 2 1], |
|
2797 Cn 2 rec_right [id 2 1]]], |
|
2798 Cn 2 rec_newstat [id 2 0, |
|
2799 Cn 2 rec_stat [id 2 1], |
|
2800 Cn 2 rec_right [id 2 1]], |
|
2801 Cn 2 rec_newrght [Cn 2 rec_left [id 2 1], |
|
2802 Cn 2 rec_right [id 2 1], |
|
2803 Cn 2 rec_actn [id 2 0, |
|
2804 Cn 2 rec_stat [id 2 1], |
|
2805 Cn 2 rec_right [id 2 1]]]]" |
|
2806 |
|
2807 lemma newconf_lemma: "rec_exec rec_newconf [m ,c] = newconf m c" |
|
2808 by(auto simp: rec_newconf_def rec_exec.simps |
|
2809 trpl_lemma newleft_lemma left_lemma |
|
2810 right_lemma stat_lemma newrght_lemma actn_lemma |
|
2811 newstat_lemma stat_lemma newconf.simps) |
|
2812 |
|
2813 declare newconf_lemma[simp] |
|
2814 |
|
2815 text {* |
|
2816 @{text "conf m r k"} computes the TM configuration after @{text "k"} steps of execution |
|
2817 of TM coded as @{text "m"} starting from the initial configuration where the left number equals @{text "0"}, |
|
2818 right number equals @{text "r"}. |
|
2819 *} |
|
2820 fun conf :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat" |
|
2821 where |
|
2822 "conf m r 0 = trpl 0 (Suc 0) r" |
|
2823 | "conf m r (Suc t) = newconf m (conf m r t)" |
|
2824 |
|
2825 declare conf.simps[simp del] |
|
2826 |
|
2827 text {* |
|
2828 @{text "conf"} is implemented by the following recursive function @{text "rec_conf"}. |
|
2829 *} |
|
2830 definition rec_conf :: "recf" |
|
2831 where |
|
2832 "rec_conf = Pr 2 (Cn 2 rec_trpl [Cn 2 (constn 0) [id 2 0], Cn 2 (constn (Suc 0)) [id 2 0], id 2 1]) |
|
2833 (Cn 4 rec_newconf [id 4 0, id 4 3])" |
|
2834 |
|
2835 lemma conf_step: |
|
2836 "rec_exec rec_conf [m, r, Suc t] = |
|
2837 rec_exec rec_newconf [m, rec_exec rec_conf [m, r, t]]" |
|
2838 proof - |
|
2839 have "rec_exec rec_conf ([m, r] @ [Suc t]) = |
|
2840 rec_exec rec_newconf [m, rec_exec rec_conf [m, r, t]]" |
|
2841 by(simp only: rec_conf_def rec_pr_Suc_simp_rewrite, |
|
2842 simp add: rec_exec.simps) |
|
2843 thus "rec_exec rec_conf [m, r, Suc t] = |
|
2844 rec_exec rec_newconf [m, rec_exec rec_conf [m, r, t]]" |
|
2845 by simp |
|
2846 qed |
|
2847 |
|
2848 text {* |
|
2849 The correctness of @{text "rec_conf"}. |
|
2850 *} |
|
2851 lemma conf_lemma: |
|
2852 "rec_exec rec_conf [m, r, t] = conf m r t" |
|
2853 apply(induct t) |
|
2854 apply(simp add: rec_conf_def rec_exec.simps conf.simps inpt_lemma trpl_lemma) |
|
2855 apply(simp add: conf_step conf.simps) |
|
2856 done |
|
2857 |
|
2858 text {* |
|
2859 @{text "NSTD c"} returns true if the configureation coded by @{text "c"} is no a stardard |
|
2860 final configuration. |
|
2861 *} |
|
2862 fun NSTD :: "nat \<Rightarrow> bool" |
|
2863 where |
|
2864 "NSTD c = (stat c \<noteq> 0 \<or> left c \<noteq> 0 \<or> |
|
2865 rght c \<noteq> 2^(lg (rght c + 1) 2) - 1 \<or> rght c = 0)" |
|
2866 |
|
2867 text {* |
|
2868 @{text "rec_NSTD"} is the recursive function implementing @{text "NSTD"}. |
|
2869 *} |
|
2870 definition rec_NSTD :: "recf" |
|
2871 where |
|
2872 "rec_NSTD = |
|
2873 Cn 1 rec_disj [ |
|
2874 Cn 1 rec_disj [ |
|
2875 Cn 1 rec_disj |
|
2876 [Cn 1 rec_noteq [rec_stat, constn 0], |
|
2877 Cn 1 rec_noteq [rec_left, constn 0]] , |
|
2878 Cn 1 rec_noteq [rec_right, |
|
2879 Cn 1 rec_minus [Cn 1 rec_power |
|
2880 [constn 2, Cn 1 rec_lg |
|
2881 [Cn 1 rec_add |
|
2882 [rec_right, constn 1], |
|
2883 constn 2]], constn 1]]], |
|
2884 Cn 1 rec_eq [rec_right, constn 0]]" |
|
2885 |
|
2886 lemma NSTD_lemma1: "rec_exec rec_NSTD [c] = Suc 0 \<or> |
|
2887 rec_exec rec_NSTD [c] = 0" |
|
2888 by(simp add: rec_exec.simps rec_NSTD_def) |
|
2889 |
|
2890 declare NSTD.simps[simp del] |
|
2891 lemma NSTD_lemma2': "(rec_exec rec_NSTD [c] = Suc 0) \<Longrightarrow> NSTD c" |
|
2892 apply(simp add: rec_exec.simps rec_NSTD_def stat_lemma left_lemma |
|
2893 lg_lemma right_lemma power_lemma NSTD.simps eq_lemma) |
|
2894 apply(auto) |
|
2895 apply(case_tac "0 < left c", simp, simp) |
|
2896 done |
|
2897 |
|
2898 lemma NSTD_lemma2'': |
|
2899 "NSTD c \<Longrightarrow> (rec_exec rec_NSTD [c] = Suc 0)" |
|
2900 apply(simp add: rec_exec.simps rec_NSTD_def stat_lemma |
|
2901 left_lemma lg_lemma right_lemma power_lemma NSTD.simps) |
|
2902 apply(auto split: if_splits) |
|
2903 done |
|
2904 |
|
2905 text {* |
|
2906 The correctness of @{text "NSTD"}. |
|
2907 *} |
|
2908 lemma NSTD_lemma2: "(rec_exec rec_NSTD [c] = Suc 0) = NSTD c" |
|
2909 using NSTD_lemma1 |
|
2910 apply(auto intro: NSTD_lemma2' NSTD_lemma2'') |
|
2911 done |
|
2912 |
|
2913 fun nstd :: "nat \<Rightarrow> nat" |
|
2914 where |
|
2915 "nstd c = (if NSTD c then 1 else 0)" |
|
2916 |
|
2917 lemma nstd_lemma: "rec_exec rec_NSTD [c] = nstd c" |
|
2918 using NSTD_lemma1 |
|
2919 apply(simp add: NSTD_lemma2, auto) |
|
2920 done |
|
2921 |
|
2922 text {* GGGGGGGGGGGGGGGGGGGGGGG *} |
|
2923 |
|
2924 text{* |
|
2925 @{text "nonstep m r t"} means afer @{text "t"} steps of execution, the TM coded by @{text "m"} |
|
2926 is not at a stardard final configuration. |
|
2927 *} |
|
2928 fun nonstop :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat" |
|
2929 where |
|
2930 "nonstop m r t = nstd (conf m r t)" |
|
2931 |
|
2932 text {* |
|
2933 @{text "rec_nonstop"} is the recursive function implementing @{text "nonstop"}. |
|
2934 *} |
|
2935 definition rec_nonstop :: "recf" |
|
2936 where |
|
2937 "rec_nonstop = Cn 3 rec_NSTD [rec_conf]" |
|
2938 |
|
2939 text {* |
|
2940 The correctness of @{text "rec_nonstop"}. |
|
2941 *} |
|
2942 lemma nonstop_lemma: |
|
2943 "rec_exec rec_nonstop [m, r, t] = nonstop m r t" |
|
2944 apply(simp add: rec_exec.simps rec_nonstop_def nstd_lemma conf_lemma) |
|
2945 done |
|
2946 |
|
2947 text{* |
|
2948 @{text "rec_halt"} is the recursive function calculating the steps a TM needs to execute before |
|
2949 to reach a stardard final configuration. This recursive function is the only one |
|
2950 using @{text "Mn"} combinator. So it is the only non-primitive recursive function |
|
2951 needs to be used in the construction of the universal function @{text "F"}. |
|
2952 *} |
|
2953 |
|
2954 definition rec_halt :: "recf" |
|
2955 where |
|
2956 "rec_halt = Mn (Suc (Suc 0)) (rec_nonstop)" |
|
2957 |
|
2958 declare nonstop.simps[simp del] |
|
2959 |
|
2960 (* when mn, use rec_calc_rel instead of rec_exec*) |
|
2961 |
|
2962 lemma primerec_not0: "primerec f n \<Longrightarrow> n > 0" |
|
2963 by(induct f n rule: primerec.induct, auto) |
|
2964 |
|
2965 lemma [elim]: "primerec f 0 \<Longrightarrow> RR" |
|
2966 apply(drule_tac primerec_not0, simp) |
|
2967 done |
|
2968 |
|
2969 lemma [simp]: "length xs = Suc n \<Longrightarrow> length (butlast xs) = n" |
|
2970 apply(subgoal_tac "\<exists> y ys. xs = ys @ [y]", auto) |
|
2971 apply(rule_tac x = "last xs" in exI) |
|
2972 apply(rule_tac x = "butlast xs" in exI) |
|
2973 apply(case_tac "xs = []", auto) |
|
2974 done |
|
2975 |
|
2976 text {* |
|
2977 The lemma relates the interpreter of primitive fucntions with |
|
2978 the calculation relation of general recursive functions. |
|
2979 *} |
|
2980 lemma prime_rel_exec_eq: "primerec r (length xs) |
|
2981 \<Longrightarrow> rec_calc_rel r xs rs = (rec_exec r xs = rs)" |
|
2982 proof(induct r xs arbitrary: rs rule: rec_exec.induct, simp_all) |
|
2983 fix xs rs |
|
2984 assume "primerec z (length (xs::nat list))" |
|
2985 hence "length xs = Suc 0" by(erule_tac prime_z_reverse, simp) |
|
2986 thus "rec_calc_rel z xs rs = (rec_exec z xs = rs)" |
|
2987 apply(case_tac xs, simp, auto) |
|
2988 apply(erule_tac calc_z_reverse, simp add: rec_exec.simps) |
|
2989 apply(simp add: rec_exec.simps, rule_tac calc_z) |
|
2990 done |
|
2991 next |
|
2992 fix xs rs |
|
2993 assume "primerec s (length (xs::nat list))" |
|
2994 hence "length xs = Suc 0" .. |
|
2995 thus "rec_calc_rel s xs rs = (rec_exec s xs = rs)" |
|
2996 by(case_tac xs, auto simp: rec_exec.simps intro: calc_s |
|
2997 elim: calc_s_reverse) |
|
2998 next |
|
2999 fix m n xs rs |
|
3000 assume "primerec (recf.id m n) (length (xs::nat list))" |
|
3001 thus |
|
3002 "rec_calc_rel (recf.id m n) xs rs = |
|
3003 (rec_exec (recf.id m n) xs = rs)" |
|
3004 apply(erule_tac prime_id_reverse) |
|
3005 apply(simp add: rec_exec.simps, auto) |
|
3006 apply(erule_tac calc_id_reverse, simp) |
|
3007 apply(rule_tac calc_id, auto) |
|
3008 done |
|
3009 next |
|
3010 fix n f gs xs rs |
|
3011 assume ind1: |
|
3012 "\<And>x rs. \<lbrakk>x \<in> set gs; primerec x (length xs)\<rbrakk> \<Longrightarrow> |
|
3013 rec_calc_rel x xs rs = (rec_exec x xs = rs)" |
|
3014 and ind2: |
|
3015 "\<And>x rs. \<lbrakk>x = map (\<lambda>a. rec_exec a xs) gs; |
|
3016 primerec f (length gs)\<rbrakk> \<Longrightarrow> |
|
3017 rec_calc_rel f (map (\<lambda>a. rec_exec a xs) gs) rs = |
|
3018 (rec_exec f (map (\<lambda>a. rec_exec a xs) gs) = rs)" |
|
3019 and h: "primerec (Cn n f gs) (length xs)" |
|
3020 show "rec_calc_rel (Cn n f gs) xs rs = |
|
3021 (rec_exec (Cn n f gs) xs = rs)" |
|
3022 proof(auto simp: rec_exec.simps, erule_tac calc_cn_reverse, auto) |
|
3023 fix ys |
|
3024 assume g1:"\<forall>k<length gs. rec_calc_rel (gs ! k) xs (ys ! k)" |
|
3025 and g2: "length ys = length gs" |
|
3026 and g3: "rec_calc_rel f ys rs" |
|
3027 have "rec_calc_rel f (map (\<lambda>a. rec_exec a xs) gs) rs = |
|
3028 (rec_exec f (map (\<lambda>a. rec_exec a xs) gs) = rs)" |
|
3029 apply(rule_tac ind2, auto) |
|
3030 using h |
|
3031 apply(erule_tac prime_cn_reverse, simp) |
|
3032 done |
|
3033 moreover have "ys = (map (\<lambda>a. rec_exec a xs) gs)" |
|
3034 proof(rule_tac nth_equalityI, auto simp: g2) |
|
3035 fix i |
|
3036 assume "i < length gs" thus "ys ! i = rec_exec (gs!i) xs" |
|
3037 using ind1[of "gs ! i" "ys ! i"] g1 h |
|
3038 apply(erule_tac prime_cn_reverse, simp) |
|
3039 done |
|
3040 qed |
|
3041 ultimately show "rec_exec f (map (\<lambda>a. rec_exec a xs) gs) = rs" |
|
3042 using g3 |
|
3043 by(simp) |
|
3044 next |
|
3045 from h show |
|
3046 "rec_calc_rel (Cn n f gs) xs |
|
3047 (rec_exec f (map (\<lambda>a. rec_exec a xs) gs))" |
|
3048 apply(rule_tac rs = "(map (\<lambda>a. rec_exec a xs) gs)" in calc_cn, |
|
3049 auto) |
|
3050 apply(erule_tac [!] prime_cn_reverse, auto) |
|
3051 proof - |
|
3052 fix k |
|
3053 assume "k < length gs" "primerec f (length gs)" |
|
3054 "\<forall>i<length gs. primerec (gs ! i) (length xs)" |
|
3055 thus "rec_calc_rel (gs ! k) xs (rec_exec (gs ! k) xs)" |
|
3056 using ind1[of "gs!k" "(rec_exec (gs ! k) xs)"] |
|
3057 by(simp) |
|
3058 next |
|
3059 assume "primerec f (length gs)" |
|
3060 "\<forall>i<length gs. primerec (gs ! i) (length xs)" |
|
3061 thus "rec_calc_rel f (map (\<lambda>a. rec_exec a xs) gs) |
|
3062 (rec_exec f (map (\<lambda>a. rec_exec a xs) gs))" |
|
3063 using ind2[of "(map (\<lambda>a. rec_exec a xs) gs)" |
|
3064 "(rec_exec f (map (\<lambda>a. rec_exec a xs) gs))"] |
|
3065 by simp |
|
3066 qed |
|
3067 qed |
|
3068 next |
|
3069 fix n f g xs rs |
|
3070 assume ind1: |
|
3071 "\<And>rs. \<lbrakk>last xs = 0; primerec f (length xs - Suc 0)\<rbrakk> |
|
3072 \<Longrightarrow> rec_calc_rel f (butlast xs) rs = |
|
3073 (rec_exec f (butlast xs) = rs)" |
|
3074 and ind2 : |
|
3075 "\<And>rs. \<lbrakk>0 < last xs; |
|
3076 primerec (Pr n f g) (Suc (length xs - Suc 0))\<rbrakk> \<Longrightarrow> |
|
3077 rec_calc_rel (Pr n f g) (butlast xs @ [last xs - Suc 0]) rs |
|
3078 = (rec_exec (Pr n f g) (butlast xs @ [last xs - Suc 0]) = rs)" |
|
3079 and ind3: |
|
3080 "\<And>rs. \<lbrakk>0 < last xs; primerec g (Suc (Suc (length xs - Suc 0)))\<rbrakk> |
|
3081 \<Longrightarrow> rec_calc_rel g (butlast xs @ |
|
3082 [last xs - Suc 0, rec_exec (Pr n f g) |
|
3083 (butlast xs @ [last xs - Suc 0])]) rs = |
|
3084 (rec_exec g (butlast xs @ [last xs - Suc 0, |
|
3085 rec_exec (Pr n f g) |
|
3086 (butlast xs @ [last xs - Suc 0])]) = rs)" |
|
3087 and h: "primerec (Pr n f g) (length (xs::nat list))" |
|
3088 show "rec_calc_rel (Pr n f g) xs rs = (rec_exec (Pr n f g) xs = rs)" |
|
3089 proof(auto) |
|
3090 assume "rec_calc_rel (Pr n f g) xs rs" |
|
3091 thus "rec_exec (Pr n f g) xs = rs" |
|
3092 proof(erule_tac calc_pr_reverse) |
|
3093 fix l |
|
3094 assume g: "xs = l @ [0]" |
|
3095 "rec_calc_rel f l rs" |
|
3096 "n = length l" |
|
3097 thus "rec_exec (Pr n f g) xs = rs" |
|
3098 using ind1[of rs] h |
|
3099 apply(simp add: rec_exec.simps, |
|
3100 erule_tac prime_pr_reverse, simp) |
|
3101 done |
|
3102 next |
|
3103 fix l y ry |
|
3104 assume d:"xs = l @ [Suc y]" |
|
3105 "rec_calc_rel (Pr (length l) f g) (l @ [y]) ry" |
|
3106 "n = length l" |
|
3107 "rec_calc_rel g (l @ [y, ry]) rs" |
|
3108 moreover hence "primerec g (Suc (Suc n))" using h |
|
3109 proof(erule_tac prime_pr_reverse) |
|
3110 assume "primerec g (Suc (Suc n))" "length xs = Suc n" |
|
3111 thus "?thesis" by simp |
|
3112 qed |
|
3113 ultimately show "rec_exec (Pr n f g) xs = rs" |
|
3114 apply(simp) |
|
3115 using ind3[of rs] |
|
3116 apply(simp add: rec_pr_Suc_simp_rewrite) |
|
3117 using ind2[of ry] h |
|
3118 apply(simp) |
|
3119 done |
|
3120 qed |
|
3121 next |
|
3122 show "rec_calc_rel (Pr n f g) xs (rec_exec (Pr n f g) xs)" |
|
3123 proof - |
|
3124 have "rec_calc_rel (Pr n f g) (butlast xs @ [last xs]) |
|
3125 (rec_exec (Pr n f g) (butlast xs @ [last xs]))" |
|
3126 using h |
|
3127 apply(erule_tac prime_pr_reverse, simp) |
|
3128 apply(case_tac "last xs", simp) |
|
3129 apply(rule_tac calc_pr_zero, simp) |
|
3130 using ind1[of "rec_exec (Pr n f g) (butlast xs @ [0])"] |
|
3131 apply(simp add: rec_exec.simps, simp, simp, simp) |
|
3132 thm calc_pr_ind |
|
3133 apply(rule_tac rk = "rec_exec (Pr n f g) |
|
3134 (butlast xs@[last xs - Suc 0])" in calc_pr_ind) |
|
3135 using ind2[of "rec_exec (Pr n f g) |
|
3136 (butlast xs @ [last xs - Suc 0])"] h |
|
3137 apply(simp, simp, simp) |
|
3138 proof - |
|
3139 fix nat |
|
3140 assume "length xs = Suc n" |
|
3141 "primerec g (Suc (Suc n))" |
|
3142 "last xs = Suc nat" |
|
3143 thus |
|
3144 "rec_calc_rel g (butlast xs @ [nat, rec_exec (Pr n f g) |
|
3145 (butlast xs @ [nat])]) (rec_exec (Pr n f g) (butlast xs @ [Suc nat]))" |
|
3146 using ind3[of "rec_exec (Pr n f g) |
|
3147 (butlast xs @ [Suc nat])"] |
|
3148 apply(simp add: rec_exec.simps) |
|
3149 done |
|
3150 qed |
|
3151 thus "rec_calc_rel (Pr n f g) xs (rec_exec (Pr n f g) xs)" |
|
3152 using h |
|
3153 apply(erule_tac prime_pr_reverse, simp) |
|
3154 apply(subgoal_tac "butlast xs @ [last xs] = xs", simp) |
|
3155 apply(case_tac xs, simp, simp) |
|
3156 done |
|
3157 qed |
|
3158 qed |
|
3159 next |
|
3160 fix n f xs rs |
|
3161 assume "primerec (Mn n f) (length (xs::nat list))" |
|
3162 thus "rec_calc_rel (Mn n f) xs rs = (rec_exec (Mn n f) xs = rs)" |
|
3163 by(erule_tac prime_mn_reverse) |
|
3164 qed |
|
3165 |
|
3166 declare numeral_2_eq_2[simp] numeral_3_eq_3[simp] |
|
3167 |
|
3168 lemma [intro]: "primerec rec_right (Suc 0)" |
|
3169 apply(simp add: rec_right_def rec_lo_def Let_def) |
|
3170 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3171 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3172 done |
|
3173 |
|
3174 lemma [simp]: |
|
3175 "rec_calc_rel rec_right [r] rs = (rec_exec rec_right [r] = rs)" |
|
3176 apply(rule_tac prime_rel_exec_eq, auto) |
|
3177 done |
|
3178 |
|
3179 lemma [intro]: "primerec rec_pi (Suc 0)" |
|
3180 apply(simp add: rec_pi_def rec_dummy_pi_def |
|
3181 rec_np_def rec_fac_def rec_prime_def |
|
3182 rec_Minr.simps Let_def get_fstn_args.simps |
|
3183 arity.simps |
|
3184 rec_all.simps rec_sigma.simps rec_accum.simps) |
|
3185 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3186 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3187 apply(simp add: rec_dummyfac_def) |
|
3188 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3189 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3190 done |
|
3191 |
|
3192 lemma [intro]: "primerec rec_trpl (Suc (Suc (Suc 0)))" |
|
3193 apply(simp add: rec_trpl_def) |
|
3194 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3195 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3196 done |
|
3197 |
|
3198 lemma [intro!]: "\<lbrakk>0 < vl; n \<le> vl\<rbrakk> \<Longrightarrow> primerec (rec_listsum2 vl n) vl" |
|
3199 apply(induct n) |
|
3200 apply(simp_all add: rec_strt'.simps Let_def rec_listsum2.simps) |
|
3201 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3202 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3203 done |
|
3204 |
|
3205 lemma [elim]: "\<lbrakk>0 < vl; n \<le> vl\<rbrakk> \<Longrightarrow> primerec (rec_strt' vl n) vl" |
|
3206 apply(induct n) |
|
3207 apply(simp_all add: rec_strt'.simps Let_def) |
|
3208 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3209 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+) |
|
3210 done |
|
3211 |
|
3212 lemma [elim]: "vl > 0 \<Longrightarrow> primerec (rec_strt vl) vl" |
|
3213 apply(simp add: rec_strt.simps rec_strt'.simps) |
|
3214 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3215 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3216 done |
|
3217 |
|
3218 lemma [elim]: |
|
3219 "i < vl \<Longrightarrow> primerec ((map (\<lambda>i. recf.id (Suc vl) (i)) |
|
3220 [Suc 0..<vl] @ [recf.id (Suc vl) (vl)]) ! i) (Suc vl)" |
|
3221 apply(induct i, auto simp: nth_append) |
|
3222 done |
|
3223 |
|
3224 lemma [intro]: "primerec rec_newleft0 ((Suc (Suc 0)))" |
|
3225 apply(simp add: rec_newleft_def rec_embranch.simps |
|
3226 Let_def arity.simps rec_newleft0_def |
|
3227 rec_newleft1_def rec_newleft2_def rec_newleft3_def) |
|
3228 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3229 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3230 done |
|
3231 |
|
3232 lemma [intro]: "primerec rec_newleft1 ((Suc (Suc 0)))" |
|
3233 apply(simp add: rec_newleft_def rec_embranch.simps |
|
3234 Let_def arity.simps rec_newleft0_def |
|
3235 rec_newleft1_def rec_newleft2_def rec_newleft3_def) |
|
3236 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3237 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3238 done |
|
3239 |
|
3240 lemma [intro]: "primerec rec_newleft2 ((Suc (Suc 0)))" |
|
3241 apply(simp add: rec_newleft_def rec_embranch.simps |
|
3242 Let_def arity.simps rec_newleft0_def |
|
3243 rec_newleft1_def rec_newleft2_def rec_newleft3_def) |
|
3244 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3245 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3246 done |
|
3247 |
|
3248 lemma [intro]: "primerec rec_newleft3 ((Suc (Suc 0)))" |
|
3249 apply(simp add: rec_newleft_def rec_embranch.simps |
|
3250 Let_def arity.simps rec_newleft0_def |
|
3251 rec_newleft1_def rec_newleft2_def rec_newleft3_def) |
|
3252 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3253 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3254 done |
|
3255 |
|
3256 lemma [intro]: "primerec rec_newleft (Suc (Suc (Suc 0)))" |
|
3257 apply(simp add: rec_newleft_def rec_embranch.simps |
|
3258 Let_def arity.simps) |
|
3259 apply(rule_tac prime_cn, auto+) |
|
3260 done |
|
3261 |
|
3262 lemma [intro]: "primerec rec_left (Suc 0)" |
|
3263 apply(simp add: rec_left_def rec_lo_def rec_entry_def Let_def) |
|
3264 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3265 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3266 done |
|
3267 |
|
3268 lemma [intro]: "primerec rec_actn (Suc (Suc (Suc 0)))" |
|
3269 apply(simp add: rec_left_def rec_lo_def rec_entry_def |
|
3270 Let_def rec_actn_def) |
|
3271 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3272 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3273 done |
|
3274 |
|
3275 lemma [intro]: "primerec rec_stat (Suc 0)" |
|
3276 apply(simp add: rec_left_def rec_lo_def rec_entry_def Let_def |
|
3277 rec_actn_def rec_stat_def) |
|
3278 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3279 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3280 done |
|
3281 |
|
3282 lemma [intro]: "primerec rec_newstat (Suc (Suc (Suc 0)))" |
|
3283 apply(simp add: rec_left_def rec_lo_def rec_entry_def |
|
3284 Let_def rec_actn_def rec_stat_def rec_newstat_def) |
|
3285 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3286 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3287 done |
|
3288 |
|
3289 lemma [intro]: "primerec rec_newrght (Suc (Suc (Suc 0)))" |
|
3290 apply(simp add: rec_newrght_def rec_embranch.simps |
|
3291 Let_def arity.simps rec_newrgt0_def |
|
3292 rec_newrgt1_def rec_newrgt2_def rec_newrgt3_def) |
|
3293 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3294 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3295 done |
|
3296 |
|
3297 lemma [intro]: "primerec rec_newconf (Suc (Suc 0))" |
|
3298 apply(simp add: rec_newconf_def) |
|
3299 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3300 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3301 done |
|
3302 |
|
3303 lemma [intro]: "0 < vl \<Longrightarrow> primerec (rec_inpt (Suc vl)) (Suc vl)" |
|
3304 apply(simp add: rec_inpt_def) |
|
3305 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3306 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3307 done |
|
3308 |
|
3309 lemma [intro]: "primerec rec_conf (Suc (Suc (Suc 0)))" |
|
3310 apply(simp add: rec_conf_def) |
|
3311 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3312 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3313 apply(auto simp: numeral_4_eq_4) |
|
3314 done |
|
3315 |
|
3316 lemma [simp]: |
|
3317 "rec_calc_rel rec_conf [m, r, t] rs = |
|
3318 (rec_exec rec_conf [m, r, t] = rs)" |
|
3319 apply(rule_tac prime_rel_exec_eq, auto) |
|
3320 done |
|
3321 |
|
3322 lemma [intro]: "primerec rec_lg (Suc (Suc 0))" |
|
3323 apply(simp add: rec_lg_def Let_def) |
|
3324 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3325 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3326 done |
|
3327 |
|
3328 lemma [intro]: "primerec rec_nonstop (Suc (Suc (Suc 0)))" |
|
3329 apply(simp add: rec_nonstop_def rec_NSTD_def rec_stat_def |
|
3330 rec_lo_def Let_def rec_left_def rec_right_def rec_newconf_def |
|
3331 rec_newstat_def) |
|
3332 apply(tactic {* resolve_tac [@{thm prime_cn}, |
|
3333 @{thm prime_id}, @{thm prime_pr}] 1*}, auto+)+ |
|
3334 done |
|
3335 |
|
3336 lemma nonstop_eq[simp]: |
|
3337 "rec_calc_rel rec_nonstop [m, r, t] rs = |
|
3338 (rec_exec rec_nonstop [m, r, t] = rs)" |
|
3339 apply(rule prime_rel_exec_eq, auto) |
|
3340 done |
|
3341 |
|
3342 lemma halt_lemma': |
|
3343 "rec_calc_rel rec_halt [m, r] t = |
|
3344 (rec_calc_rel rec_nonstop [m, r, t] 0 \<and> |
|
3345 (\<forall> t'< t. |
|
3346 (\<exists> y. rec_calc_rel rec_nonstop [m, r, t'] y \<and> |
|
3347 y \<noteq> 0)))" |
|
3348 apply(auto simp: rec_halt_def) |
|
3349 apply(erule calc_mn_reverse, simp) |
|
3350 apply(erule_tac calc_mn_reverse) |
|
3351 apply(erule_tac x = t' in allE, simp) |
|
3352 apply(rule_tac calc_mn, simp_all) |
|
3353 done |
|
3354 |
|
3355 text {* |
|
3356 The following lemma gives the correctness of @{text "rec_halt"}. |
|
3357 It says: if @{text "rec_halt"} calculates that the TM coded by @{text "m"} |
|
3358 will reach a standard final configuration after @{text "t"} steps of execution, then it is indeed so. |
|
3359 *} |
|
3360 lemma halt_lemma: |
|
3361 "rec_calc_rel (rec_halt) [m, r] t = |
|
3362 (rec_exec rec_nonstop [m, r, t] = 0 \<and> |
|
3363 (\<forall> t'< t. (\<exists> y. rec_exec rec_nonstop [m, r, t'] = y |
|
3364 \<and> y \<noteq> 0)))" |
|
3365 using halt_lemma'[of m r t] |
|
3366 by simp |
|
3367 |
|
3368 text {*F: universal machine*} |
|
3369 |
|
3370 text {* |
|
3371 @{text "valu r"} extracts computing result out of the right number @{text "r"}. |
|
3372 *} |
|
3373 fun valu :: "nat \<Rightarrow> nat" |
|
3374 where |
|
3375 "valu r = (lg (r + 1) 2) - 1" |
|
3376 |
|
3377 text {* |
|
3378 @{text "rec_valu"} is the recursive function implementing @{text "valu"}. |
|
3379 *} |
|
3380 definition rec_valu :: "recf" |
|
3381 where |
|
3382 "rec_valu = Cn 1 rec_minus [Cn 1 rec_lg [s, constn 2], constn 1]" |
|
3383 |
|
3384 text {* |
|
3385 The correctness of @{text "rec_valu"}. |
|
3386 *} |
|
3387 lemma value_lemma: "rec_exec rec_valu [r] = valu r" |
|
3388 apply(simp add: rec_exec.simps rec_valu_def lg_lemma) |
|
3389 done |
|
3390 |
|
3391 lemma [intro]: "primerec rec_valu (Suc 0)" |
|
3392 apply(simp add: rec_valu_def) |
|
3393 apply(rule_tac k = "Suc (Suc 0)" in prime_cn) |
|
3394 apply(auto simp: prime_s) |
|
3395 proof - |
|
3396 show "primerec rec_lg (Suc (Suc 0))" by auto |
|
3397 next |
|
3398 show "Suc (Suc 0) = Suc (Suc 0)" by simp |
|
3399 next |
|
3400 show "primerec (constn (Suc (Suc 0))) (Suc 0)" by auto |
|
3401 qed |
|
3402 |
|
3403 lemma [simp]: "rec_calc_rel rec_valu [r] rs = |
|
3404 (rec_exec rec_valu [r] = rs)" |
|
3405 apply(rule_tac prime_rel_exec_eq, auto) |
|
3406 done |
|
3407 |
|
3408 declare valu.simps[simp del] |
|
3409 |
|
3410 text {* |
|
3411 The definition of the universal function @{text "rec_F"}. |
|
3412 *} |
|
3413 definition rec_F :: "recf" |
|
3414 where |
|
3415 "rec_F = Cn (Suc (Suc 0)) rec_valu [Cn (Suc (Suc 0)) rec_right [Cn (Suc (Suc 0)) |
|
3416 rec_conf ([id (Suc (Suc 0)) 0, id (Suc (Suc 0)) (Suc 0), rec_halt])]]" |
|
3417 |
|
3418 lemma get_fstn_args_nth: |
|
3419 "k < n \<Longrightarrow> (get_fstn_args m n ! k) = id m (k)" |
|
3420 apply(induct n, simp) |
|
3421 apply(case_tac "k = n", simp_all add: get_fstn_args.simps |
|
3422 nth_append) |
|
3423 done |
|
3424 |
|
3425 lemma [simp]: |
|
3426 "\<lbrakk>ys \<noteq> []; k < length ys\<rbrakk> \<Longrightarrow> |
|
3427 (get_fstn_args (length ys) (length ys) ! k) = |
|
3428 id (length ys) (k)" |
|
3429 by(erule_tac get_fstn_args_nth) |
|
3430 |
|
3431 lemma calc_rel_get_pren: |
|
3432 "\<lbrakk>ys \<noteq> []; k < length ys\<rbrakk> \<Longrightarrow> |
|
3433 rec_calc_rel (get_fstn_args (length ys) (length ys) ! k) ys |
|
3434 (ys ! k)" |
|
3435 apply(simp) |
|
3436 apply(rule_tac calc_id, auto) |
|
3437 done |
|
3438 |
|
3439 lemma [elim]: |
|
3440 "\<lbrakk>xs \<noteq> []; k < Suc (length xs)\<rbrakk> \<Longrightarrow> |
|
3441 rec_calc_rel (get_fstn_args (Suc (length xs)) |
|
3442 (Suc (length xs)) ! k) (m # xs) ((m # xs) ! k)" |
|
3443 using calc_rel_get_pren[of "m#xs" k] |
|
3444 apply(simp) |
|
3445 done |
|
3446 |
|
3447 text {* |
|
3448 The correctness of @{text "rec_F"}, halt case. |
|
3449 *} |
|
3450 lemma F_lemma: |
|
3451 "rec_calc_rel rec_halt [m, r] t \<Longrightarrow> |
|
3452 rec_calc_rel rec_F [m, r] (valu (rght (conf m r t)))" |
|
3453 apply(simp add: rec_F_def) |
|
3454 apply(rule_tac rs = "[rght (conf m r t)]" in calc_cn, |
|
3455 auto simp: value_lemma) |
|
3456 apply(rule_tac rs = "[conf m r t]" in calc_cn, |
|
3457 auto simp: right_lemma) |
|
3458 apply(rule_tac rs = "[m, r, t]" in calc_cn, auto) |
|
3459 apply(subgoal_tac " k = 0 \<or> k = Suc 0 \<or> k = Suc (Suc 0)", |
|
3460 auto simp:nth_append) |
|
3461 apply(rule_tac [1-2] calc_id, simp_all add: conf_lemma) |
|
3462 done |
|
3463 |
|
3464 |
|
3465 text {* |
|
3466 The correctness of @{text "rec_F"}, nonhalt case. |
|
3467 *} |
|
3468 lemma F_lemma2: |
|
3469 "\<forall> t. \<not> rec_calc_rel rec_halt [m, r] t \<Longrightarrow> |
|
3470 \<forall> rs. \<not> rec_calc_rel rec_F [m, r] rs" |
|
3471 apply(auto simp: rec_F_def) |
|
3472 apply(erule_tac calc_cn_reverse, simp (no_asm_use))+ |
|
3473 proof - |
|
3474 fix rs rsa rsb rsc |
|
3475 assume h: |
|
3476 "\<forall>t. \<not> rec_calc_rel rec_halt [m, r] t" |
|
3477 "length rsa = Suc 0" |
|
3478 "rec_calc_rel rec_valu rsa rs" |
|
3479 "length rsb = Suc 0" |
|
3480 "rec_calc_rel rec_right rsb (rsa ! 0)" |
|
3481 "length rsc = (Suc (Suc (Suc 0)))" |
|
3482 "rec_calc_rel rec_conf rsc (rsb ! 0)" |
|
3483 and g: "\<forall>k<Suc (Suc (Suc 0)). rec_calc_rel ([recf.id (Suc (Suc 0)) 0, |
|
3484 recf.id (Suc (Suc 0)) (Suc 0), rec_halt] ! k) [m, r] (rsc ! k)" |
|
3485 have "rec_calc_rel (rec_halt ) [m, r] |
|
3486 (rsc ! (Suc (Suc 0)))" |
|
3487 using g |
|
3488 apply(erule_tac x = "(Suc (Suc 0))" in allE) |
|
3489 apply(simp add:nth_append) |
|
3490 done |
|
3491 thus "False" |
|
3492 using h |
|
3493 apply(erule_tac x = "ysb ! (Suc (Suc 0))" in allE, simp) |
|
3494 done |
|
3495 qed |
|
3496 |
|
3497 section {* Coding function of TMs *} |
|
3498 |
|
3499 text {* |
|
3500 The purpose of this section is to get the coding function of Turing Machine, which is |
|
3501 going to be named @{text "code"}. |
|
3502 *} |
|
3503 |
|
3504 fun bl2nat :: "block list \<Rightarrow> nat \<Rightarrow> nat" |
|
3505 where |
|
3506 "bl2nat [] n = 0" |
|
3507 | "bl2nat (Bk#bl) n = bl2nat bl (Suc n)" |
|
3508 | "bl2nat (Oc#bl) n = 2^n + bl2nat bl (Suc n)" |
|
3509 |
|
3510 fun bl2wc :: "block list \<Rightarrow> nat" |
|
3511 where |
|
3512 "bl2wc xs = bl2nat xs 0" |
|
3513 |
|
3514 fun trpl_code :: "t_conf \<Rightarrow> nat" |
|
3515 where |
|
3516 "trpl_code (st, l, r) = trpl (bl2wc l) st (bl2wc r)" |
|
3517 |
|
3518 declare bl2nat.simps[simp del] bl2wc.simps[simp del] |
|
3519 trpl_code.simps[simp del] |
|
3520 |
|
3521 fun action_map :: "taction \<Rightarrow> nat" |
|
3522 where |
|
3523 "action_map W0 = 0" |
|
3524 | "action_map W1 = 1" |
|
3525 | "action_map L = 2" |
|
3526 | "action_map R = 3" |
|
3527 | "action_map Nop = 4" |
|
3528 |
|
3529 fun action_map_iff :: "nat \<Rightarrow> taction" |
|
3530 where |
|
3531 "action_map_iff (0::nat) = W0" |
|
3532 | "action_map_iff (Suc 0) = W1" |
|
3533 | "action_map_iff (Suc (Suc 0)) = L" |
|
3534 | "action_map_iff (Suc (Suc (Suc 0))) = R" |
|
3535 | "action_map_iff n = Nop" |
|
3536 |
|
3537 fun block_map :: "block \<Rightarrow> nat" |
|
3538 where |
|
3539 "block_map Bk = 0" |
|
3540 | "block_map Oc = 1" |
|
3541 |
|
3542 fun godel_code' :: "nat list \<Rightarrow> nat \<Rightarrow> nat" |
|
3543 where |
|
3544 "godel_code' [] n = 1" |
|
3545 | "godel_code' (x#xs) n = (Pi n)^x * godel_code' xs (Suc n) " |
|
3546 |
|
3547 fun godel_code :: "nat list \<Rightarrow> nat" |
|
3548 where |
|
3549 "godel_code xs = (let lh = length xs in |
|
3550 2^lh * (godel_code' xs (Suc 0)))" |
|
3551 |
|
3552 fun modify_tprog :: "tprog \<Rightarrow> nat list" |
|
3553 where |
|
3554 "modify_tprog [] = []" |
|
3555 | "modify_tprog ((ac, ns)#nl) = action_map ac # ns # modify_tprog nl" |
|
3556 |
|
3557 text {* |
|
3558 @{text "code tp"} gives the Godel coding of TM program @{text "tp"}. |
|
3559 *} |
|
3560 fun code :: "tprog \<Rightarrow> nat" |
|
3561 where |
|
3562 "code tp = (let nl = modify_tprog tp in |
|
3563 godel_code nl)" |
|
3564 |
|
3565 section {* Relating interperter functions to the execution of TMs *} |
|
3566 |
|
3567 lemma [simp]: "bl2wc [] = 0" by(simp add: bl2wc.simps bl2nat.simps) |
|
3568 term trpl |
|
3569 |
|
3570 lemma [simp]: "\<lbrakk>fetch tp 0 b = (nact, ns)\<rbrakk> \<Longrightarrow> action_map nact = 4" |
|
3571 apply(simp add: fetch.simps) |
|
3572 done |
|
3573 |
|
3574 thm entry_lemma |
|
3575 lemma Pi_gr_1[simp]: "Pi n > Suc 0" |
|
3576 proof(induct n, auto simp: Pi.simps Np.simps) |
|
3577 fix n |
|
3578 let ?setx = "{y. y \<le> Suc (Pi n!) \<and> Pi n < y \<and> Prime y}" |
|
3579 have "finite ?setx" by auto |
|
3580 moreover have "?setx \<noteq> {}" |
|
3581 using prime_ex[of "Pi n"] |
|
3582 apply(auto) |
|
3583 done |
|
3584 ultimately show "Suc 0 < Min ?setx" |
|
3585 apply(simp add: Min_gr_iff) |
|
3586 apply(auto simp: Prime.simps) |
|
3587 done |
|
3588 qed |
|
3589 |
|
3590 lemma Pi_not_0[simp]: "Pi n > 0" |
|
3591 using Pi_gr_1[of n] |
|
3592 by arith |
|
3593 |
|
3594 declare godel_code.simps[simp del] |
|
3595 |
|
3596 lemma [simp]: "0 < godel_code' nl n" |
|
3597 apply(induct nl arbitrary: n) |
|
3598 apply(auto simp: godel_code'.simps) |
|
3599 done |
|
3600 |
|
3601 lemma godel_code_great: "godel_code nl > 0" |
|
3602 apply(simp add: godel_code.simps) |
|
3603 done |
|
3604 |
|
3605 lemma godel_code_eq_1: "(godel_code nl = 1) = (nl = [])" |
|
3606 apply(auto simp: godel_code.simps) |
|
3607 done |
|
3608 |
|
3609 lemma [elim]: |
|
3610 "\<lbrakk>i < length nl; \<not> Suc 0 < godel_code nl\<rbrakk> \<Longrightarrow> nl ! i = 0" |
|
3611 using godel_code_great[of nl] godel_code_eq_1[of nl] |
|
3612 apply(simp) |
|
3613 done |
|
3614 |
|
3615 term set_of |
|
3616 lemma prime_coprime: "\<lbrakk>Prime x; Prime y; x\<noteq>y\<rbrakk> \<Longrightarrow> coprime x y" |
|
3617 proof(simp only: Prime.simps coprime_nat, auto simp: dvd_def, |
|
3618 rule_tac classical, simp) |
|
3619 fix d k ka |
|
3620 assume case_ka: "\<forall>u<d * ka. \<forall>v<d * ka. u * v \<noteq> d * ka" |
|
3621 and case_k: "\<forall>u<d * k. \<forall>v<d * k. u * v \<noteq> d * k" |
|
3622 and h: "(0::nat) < d" "d \<noteq> Suc 0" "Suc 0 < d * ka" |
|
3623 "ka \<noteq> k" "Suc 0 < d * k" |
|
3624 from h have "k > Suc 0 \<or> ka >Suc 0" |
|
3625 apply(auto) |
|
3626 apply(case_tac ka, simp, simp) |
|
3627 apply(case_tac k, simp, simp) |
|
3628 done |
|
3629 from this show "False" |
|
3630 proof(erule_tac disjE) |
|
3631 assume "(Suc 0::nat) < k" |
|
3632 hence "k < d*k \<and> d < d*k" |
|
3633 using h |
|
3634 by(auto) |
|
3635 thus "?thesis" |
|
3636 using case_k |
|
3637 apply(erule_tac x = d in allE) |
|
3638 apply(simp) |
|
3639 apply(erule_tac x = k in allE) |
|
3640 apply(simp) |
|
3641 done |
|
3642 next |
|
3643 assume "(Suc 0::nat) < ka" |
|
3644 hence "ka < d * ka \<and> d < d*ka" |
|
3645 using h by auto |
|
3646 thus "?thesis" |
|
3647 using case_ka |
|
3648 apply(erule_tac x = d in allE) |
|
3649 apply(simp) |
|
3650 apply(erule_tac x = ka in allE) |
|
3651 apply(simp) |
|
3652 done |
|
3653 qed |
|
3654 qed |
|
3655 |
|
3656 lemma Pi_inc: "Pi (Suc i) > Pi i" |
|
3657 proof(simp add: Pi.simps Np.simps) |
|
3658 let ?setx = "{y. y \<le> Suc (Pi i!) \<and> Pi i < y \<and> Prime y}" |
|
3659 have "finite ?setx" by simp |
|
3660 moreover have "?setx \<noteq> {}" |
|
3661 using prime_ex[of "Pi i"] |
|
3662 apply(auto) |
|
3663 done |
|
3664 ultimately show "Pi i < Min ?setx" |
|
3665 apply(simp add: Min_gr_iff) |
|
3666 done |
|
3667 qed |
|
3668 |
|
3669 lemma Pi_inc_gr: "i < j \<Longrightarrow> Pi i < Pi j" |
|
3670 proof(induct j, simp) |
|
3671 fix j |
|
3672 assume ind: "i < j \<Longrightarrow> Pi i < Pi j" |
|
3673 and h: "i < Suc j" |
|
3674 from h show "Pi i < Pi (Suc j)" |
|
3675 proof(cases "i < j") |
|
3676 case True thus "?thesis" |
|
3677 proof - |
|
3678 assume "i < j" |
|
3679 hence "Pi i < Pi j" by(erule_tac ind) |
|
3680 moreover have "Pi j < Pi (Suc j)" |
|
3681 apply(simp add: Pi_inc) |
|
3682 done |
|
3683 ultimately show "?thesis" |
|
3684 by simp |
|
3685 qed |
|
3686 next |
|
3687 assume "i < Suc j" "\<not> i < j" |
|
3688 hence "i = j" |
|
3689 by arith |
|
3690 thus "Pi i < Pi (Suc j)" |
|
3691 apply(simp add: Pi_inc) |
|
3692 done |
|
3693 qed |
|
3694 qed |
|
3695 |
|
3696 lemma Pi_notEq: "i \<noteq> j \<Longrightarrow> Pi i \<noteq> Pi j" |
|
3697 apply(case_tac "i < j") |
|
3698 using Pi_inc_gr[of i j] |
|
3699 apply(simp) |
|
3700 using Pi_inc_gr[of j i] |
|
3701 apply(simp) |
|
3702 done |
|
3703 |
|
3704 lemma [intro]: "Prime (Suc (Suc 0))" |
|
3705 apply(auto simp: Prime.simps) |
|
3706 apply(case_tac u, simp, case_tac nat, simp, simp) |
|
3707 done |
|
3708 |
|
3709 lemma Prime_Pi[intro]: "Prime (Pi n)" |
|
3710 proof(induct n, auto simp: Pi.simps Np.simps) |
|
3711 fix n |
|
3712 let ?setx = "{y. y \<le> Suc (Pi n!) \<and> Pi n < y \<and> Prime y}" |
|
3713 show "Prime (Min ?setx)" |
|
3714 proof - |
|
3715 have "finite ?setx" by simp |
|
3716 moreover have "?setx \<noteq> {}" |
|
3717 using prime_ex[of "Pi n"] |
|
3718 apply(simp) |
|
3719 done |
|
3720 ultimately show "?thesis" |
|
3721 apply(drule_tac Min_in, simp, simp) |
|
3722 done |
|
3723 qed |
|
3724 qed |
|
3725 |
|
3726 lemma Pi_coprime: "i \<noteq> j \<Longrightarrow> coprime (Pi i) (Pi j)" |
|
3727 using Prime_Pi[of i] |
|
3728 using Prime_Pi[of j] |
|
3729 apply(rule_tac prime_coprime, simp_all add: Pi_notEq) |
|
3730 done |
|
3731 |
|
3732 lemma Pi_power_coprime: "i \<noteq> j \<Longrightarrow> coprime ((Pi i)^m) ((Pi j)^n)" |
|
3733 by(rule_tac coprime_exp2_nat, erule_tac Pi_coprime) |
|
3734 |
|
3735 lemma coprime_dvd_mult_nat2: "\<lbrakk>coprime (k::nat) n; k dvd n * m\<rbrakk> \<Longrightarrow> k dvd m" |
|
3736 apply(erule_tac coprime_dvd_mult_nat) |
|
3737 apply(simp add: dvd_def, auto) |
|
3738 apply(rule_tac x = ka in exI) |
|
3739 apply(subgoal_tac "n * m = m * n", simp) |
|
3740 apply(simp add: nat_mult_commute) |
|
3741 done |
|
3742 |
|
3743 declare godel_code'.simps[simp del] |
|
3744 |
|
3745 lemma godel_code'_butlast_last_id' : |
|
3746 "godel_code' (ys @ [y]) (Suc j) = godel_code' ys (Suc j) * |
|
3747 Pi (Suc (length ys + j)) ^ y" |
|
3748 proof(induct ys arbitrary: j, simp_all add: godel_code'.simps) |
|
3749 qed |
|
3750 |
|
3751 lemma godel_code'_butlast_last_id: |
|
3752 "xs \<noteq> [] \<Longrightarrow> godel_code' xs (Suc j) = |
|
3753 godel_code' (butlast xs) (Suc j) * Pi (length xs + j)^(last xs)" |
|
3754 apply(subgoal_tac "\<exists> ys y. xs = ys @ [y]") |
|
3755 apply(erule_tac exE, erule_tac exE, simp add: |
|
3756 godel_code'_butlast_last_id') |
|
3757 apply(rule_tac x = "butlast xs" in exI) |
|
3758 apply(rule_tac x = "last xs" in exI, auto) |
|
3759 done |
|
3760 |
|
3761 lemma godel_code'_not0: "godel_code' xs n \<noteq> 0" |
|
3762 apply(induct xs, auto simp: godel_code'.simps) |
|
3763 done |
|
3764 |
|
3765 lemma godel_code_append_cons: |
|
3766 "length xs = i \<Longrightarrow> godel_code' (xs@y#ys) (Suc 0) |
|
3767 = godel_code' xs (Suc 0) * Pi (Suc i)^y * godel_code' ys (i + 2)" |
|
3768 proof(induct "length xs" arbitrary: i y ys xs, simp add: godel_code'.simps,simp) |
|
3769 fix x xs i y ys |
|
3770 assume ind: |
|
3771 "\<And>xs i y ys. \<lbrakk>x = i; length xs = i\<rbrakk> \<Longrightarrow> |
|
3772 godel_code' (xs @ y # ys) (Suc 0) |
|
3773 = godel_code' xs (Suc 0) * Pi (Suc i) ^ y * |
|
3774 godel_code' ys (Suc (Suc i))" |
|
3775 and h: "Suc x = i" |
|
3776 "length (xs::nat list) = i" |
|
3777 have |
|
3778 "godel_code' (butlast xs @ last xs # ((y::nat)#ys)) (Suc 0) = |
|
3779 godel_code' (butlast xs) (Suc 0) * Pi (Suc (i - 1))^(last xs) |
|
3780 * godel_code' (y#ys) (Suc (Suc (i - 1)))" |
|
3781 apply(rule_tac ind) |
|
3782 using h |
|
3783 by(auto) |
|
3784 moreover have |
|
3785 "godel_code' xs (Suc 0)= godel_code' (butlast xs) (Suc 0) * |
|
3786 Pi (i)^(last xs)" |
|
3787 using godel_code'_butlast_last_id[of xs] h |
|
3788 apply(case_tac "xs = []", simp, simp) |
|
3789 done |
|
3790 moreover have "butlast xs @ last xs # y # ys = xs @ y # ys" |
|
3791 using h |
|
3792 apply(case_tac xs, auto) |
|
3793 done |
|
3794 ultimately show |
|
3795 "godel_code' (xs @ y # ys) (Suc 0) = |
|
3796 godel_code' xs (Suc 0) * Pi (Suc i) ^ y * |
|
3797 godel_code' ys (Suc (Suc i))" |
|
3798 using h |
|
3799 apply(simp add: godel_code'_not0 Pi_not_0) |
|
3800 apply(simp add: godel_code'.simps) |
|
3801 done |
|
3802 qed |
|
3803 |
|
3804 lemma Pi_coprime_pre: |
|
3805 "length ps \<le> i \<Longrightarrow> coprime (Pi (Suc i)) (godel_code' ps (Suc 0))" |
|
3806 proof(induct "length ps" arbitrary: ps, simp add: godel_code'.simps) |
|
3807 fix x ps |
|
3808 assume ind: |
|
3809 "\<And>ps. \<lbrakk>x = length ps; length ps \<le> i\<rbrakk> \<Longrightarrow> |
|
3810 coprime (Pi (Suc i)) (godel_code' ps (Suc 0))" |
|
3811 and h: "Suc x = length ps" |
|
3812 "length (ps::nat list) \<le> i" |
|
3813 have g: "coprime (Pi (Suc i)) (godel_code' (butlast ps) (Suc 0))" |
|
3814 apply(rule_tac ind) |
|
3815 using h by auto |
|
3816 have k: "godel_code' ps (Suc 0) = |
|
3817 godel_code' (butlast ps) (Suc 0) * Pi (length ps)^(last ps)" |
|
3818 using godel_code'_butlast_last_id[of ps 0] h |
|
3819 by(case_tac ps, simp, simp) |
|
3820 from g have |
|
3821 "coprime (Pi (Suc i)) (godel_code' (butlast ps) (Suc 0) * |
|
3822 Pi (length ps)^(last ps)) " |
|
3823 proof(rule_tac coprime_mult_nat, simp) |
|
3824 show "coprime (Pi (Suc i)) (Pi (length ps) ^ last ps)" |
|
3825 apply(rule_tac coprime_exp_nat, rule prime_coprime, auto) |
|
3826 using Pi_notEq[of "Suc i" "length ps"] h by simp |
|
3827 qed |
|
3828 from this and k show "coprime (Pi (Suc i)) (godel_code' ps (Suc 0))" |
|
3829 by simp |
|
3830 qed |
|
3831 |
|
3832 lemma Pi_coprime_suf: "i < j \<Longrightarrow> coprime (Pi i) (godel_code' ps j)" |
|
3833 proof(induct "length ps" arbitrary: ps, simp add: godel_code'.simps) |
|
3834 fix x ps |
|
3835 assume ind: |
|
3836 "\<And>ps. \<lbrakk>x = length ps; i < j\<rbrakk> \<Longrightarrow> |
|
3837 coprime (Pi i) (godel_code' ps j)" |
|
3838 and h: "Suc x = length (ps::nat list)" "i < j" |
|
3839 have g: "coprime (Pi i) (godel_code' (butlast ps) j)" |
|
3840 apply(rule ind) using h by auto |
|
3841 have k: "(godel_code' ps j) = godel_code' (butlast ps) j * |
|
3842 Pi (length ps + j - 1)^last ps" |
|
3843 using h godel_code'_butlast_last_id[of ps "j - 1"] |
|
3844 apply(case_tac "ps = []", simp, simp) |
|
3845 done |
|
3846 from g have |
|
3847 "coprime (Pi i) (godel_code' (butlast ps) j * |
|
3848 Pi (length ps + j - 1)^last ps)" |
|
3849 apply(rule_tac coprime_mult_nat, simp) |
|
3850 using Pi_power_coprime[of i "length ps + j - 1" 1 "last ps"] h |
|
3851 apply(auto) |
|
3852 done |
|
3853 from k and this show "coprime (Pi i) (godel_code' ps j)" |
|
3854 by auto |
|
3855 qed |
|
3856 |
|
3857 lemma godel_finite: |
|
3858 "finite {u. Pi (Suc i) ^ u dvd godel_code' nl (Suc 0)}" |
|
3859 proof(rule_tac n = "godel_code' nl (Suc 0)" in |
|
3860 bounded_nat_set_is_finite, auto, |
|
3861 case_tac "ia < godel_code' nl (Suc 0)", auto) |
|
3862 fix ia |
|
3863 assume g1: "Pi (Suc i) ^ ia dvd godel_code' nl (Suc 0)" |
|
3864 and g2: "\<not> ia < godel_code' nl (Suc 0)" |
|
3865 from g1 have "Pi (Suc i)^ia \<le> godel_code' nl (Suc 0)" |
|
3866 apply(erule_tac dvd_imp_le) |
|
3867 using godel_code'_not0[of nl "Suc 0"] by simp |
|
3868 moreover have "ia < Pi (Suc i)^ia" |
|
3869 apply(rule x_less_exp) |
|
3870 using Pi_gr_1 by auto |
|
3871 ultimately show "False" |
|
3872 using g2 |
|
3873 by(auto) |
|
3874 qed |
|
3875 |
|
3876 |
|
3877 lemma godel_code_in: |
|
3878 "i < length nl \<Longrightarrow> nl ! i \<in> {u. Pi (Suc i) ^ u dvd |
|
3879 godel_code' nl (Suc 0)}" |
|
3880 proof - |
|
3881 assume h: "i<length nl" |
|
3882 hence "godel_code' (take i nl@(nl!i)#drop (Suc i) nl) (Suc 0) |
|
3883 = godel_code' (take i nl) (Suc 0) * Pi (Suc i)^(nl!i) * |
|
3884 godel_code' (drop (Suc i) nl) (i + 2)" |
|
3885 by(rule_tac godel_code_append_cons, simp) |
|
3886 moreover from h have "take i nl @ (nl ! i) # drop (Suc i) nl = nl" |
|
3887 using upd_conv_take_nth_drop[of i nl "nl ! i"] |
|
3888 apply(simp) |
|
3889 done |
|
3890 ultimately show |
|
3891 "nl ! i \<in> {u. Pi (Suc i) ^ u dvd godel_code' nl (Suc 0)}" |
|
3892 by(simp) |
|
3893 qed |
|
3894 |
|
3895 lemma godel_code'_get_nth: |
|
3896 "i < length nl \<Longrightarrow> Max {u. Pi (Suc i) ^ u dvd |
|
3897 godel_code' nl (Suc 0)} = nl ! i" |
|
3898 proof(rule_tac Max_eqI) |
|
3899 let ?gc = "godel_code' nl (Suc 0)" |
|
3900 assume h: "i < length nl" thus "finite {u. Pi (Suc i) ^ u dvd ?gc}" |
|
3901 by (simp add: godel_finite) |
|
3902 next |
|
3903 fix y |
|
3904 let ?suf ="godel_code' (drop (Suc i) nl) (i + 2)" |
|
3905 let ?pref = "godel_code' (take i nl) (Suc 0)" |
|
3906 assume h: "i < length nl" |
|
3907 "y \<in> {u. Pi (Suc i) ^ u dvd godel_code' nl (Suc 0)}" |
|
3908 moreover hence |
|
3909 "godel_code' (take i nl@(nl!i)#drop (Suc i) nl) (Suc 0) |
|
3910 = ?pref * Pi (Suc i)^(nl!i) * ?suf" |
|
3911 by(rule_tac godel_code_append_cons, simp) |
|
3912 moreover from h have "take i nl @ (nl!i) # drop (Suc i) nl = nl" |
|
3913 using upd_conv_take_nth_drop[of i nl "nl!i"] |
|
3914 by simp |
|
3915 ultimately show "y\<le>nl!i" |
|
3916 proof(simp) |
|
3917 let ?suf' = "godel_code' (drop (Suc i) nl) (Suc (Suc i))" |
|
3918 assume mult_dvd: |
|
3919 "Pi (Suc i) ^ y dvd ?pref * Pi (Suc i) ^ nl ! i * ?suf'" |
|
3920 hence "Pi (Suc i) ^ y dvd ?pref * Pi (Suc i) ^ nl ! i" |
|
3921 proof(rule_tac coprime_dvd_mult_nat) |
|
3922 show "coprime (Pi (Suc i)^y) ?suf'" |
|
3923 proof - |
|
3924 have "coprime (Pi (Suc i) ^ y) (?suf'^(Suc 0))" |
|
3925 apply(rule_tac coprime_exp2_nat) |
|
3926 apply(rule_tac Pi_coprime_suf, simp) |
|
3927 done |
|
3928 thus "?thesis" by simp |
|
3929 qed |
|
3930 qed |
|
3931 hence "Pi (Suc i) ^ y dvd Pi (Suc i) ^ nl ! i" |
|
3932 proof(rule_tac coprime_dvd_mult_nat2) |
|
3933 show "coprime (Pi (Suc i) ^ y) ?pref" |
|
3934 proof - |
|
3935 have "coprime (Pi (Suc i)^y) (?pref^Suc 0)" |
|
3936 apply(rule_tac coprime_exp2_nat) |
|
3937 apply(rule_tac Pi_coprime_pre, simp) |
|
3938 done |
|
3939 thus "?thesis" by simp |
|
3940 qed |
|
3941 qed |
|
3942 hence "Pi (Suc i) ^ y \<le> Pi (Suc i) ^ nl ! i " |
|
3943 apply(rule_tac dvd_imp_le, auto) |
|
3944 done |
|
3945 thus "y \<le> nl ! i" |
|
3946 apply(rule_tac power_le_imp_le_exp, auto) |
|
3947 done |
|
3948 qed |
|
3949 next |
|
3950 assume h: "i<length nl" |
|
3951 thus "nl ! i \<in> {u. Pi (Suc i) ^ u dvd godel_code' nl (Suc 0)}" |
|
3952 by(rule_tac godel_code_in, simp) |
|
3953 qed |
|
3954 |
|
3955 lemma [simp]: |
|
3956 "{u. Pi (Suc i) ^ u dvd (Suc (Suc 0)) ^ length nl * |
|
3957 godel_code' nl (Suc 0)} = |
|
3958 {u. Pi (Suc i) ^ u dvd godel_code' nl (Suc 0)}" |
|
3959 apply(rule_tac Collect_cong, auto) |
|
3960 apply(rule_tac n = " (Suc (Suc 0)) ^ length nl" in |
|
3961 coprime_dvd_mult_nat2) |
|
3962 proof - |
|
3963 fix u |
|
3964 show "coprime (Pi (Suc i) ^ u) ((Suc (Suc 0)) ^ length nl)" |
|
3965 proof(rule_tac coprime_exp2_nat) |
|
3966 have "Pi 0 = (2::nat)" |
|
3967 apply(simp add: Pi.simps) |
|
3968 done |
|
3969 moreover have "coprime (Pi (Suc i)) (Pi 0)" |
|
3970 apply(rule_tac Pi_coprime, simp) |
|
3971 done |
|
3972 ultimately show "coprime (Pi (Suc i)) (Suc (Suc 0))" by simp |
|
3973 qed |
|
3974 qed |
|
3975 |
|
3976 lemma godel_code_get_nth: |
|
3977 "i < length nl \<Longrightarrow> |
|
3978 Max {u. Pi (Suc i) ^ u dvd godel_code nl} = nl ! i" |
|
3979 by(simp add: godel_code.simps godel_code'_get_nth) |
|
3980 |
|
3981 thm trpl.simps |
|
3982 |
|
3983 lemma "trpl l st r = godel_code' [l, st, r] 0" |
|
3984 apply(simp add: trpl.simps godel_code'.simps) |
|
3985 done |
|
3986 |
|
3987 lemma mod_dvd_simp: "(x mod y = (0::nat)) = (y dvd x)" |
|
3988 by(simp add: dvd_def, auto) |
|
3989 |
|
3990 lemma dvd_power_le: "\<lbrakk>a > Suc 0; a ^ y dvd a ^ l\<rbrakk> \<Longrightarrow> y \<le> l" |
|
3991 apply(case_tac "y \<le> l", simp, simp) |
|
3992 apply(subgoal_tac "\<exists> d. y = l + d", auto simp: power_add) |
|
3993 apply(rule_tac x = "y - l" in exI, simp) |
|
3994 done |
|
3995 |
|
3996 |
|
3997 lemma [elim]: "Pi n = 0 \<Longrightarrow> RR" |
|
3998 using Pi_not_0[of n] by simp |
|
3999 |
|
4000 lemma [elim]: "Pi n = Suc 0 \<Longrightarrow> RR" |
|
4001 using Pi_gr_1[of n] by simp |
|
4002 |
|
4003 lemma finite_power_dvd: |
|
4004 "\<lbrakk>(a::nat) > Suc 0; y \<noteq> 0\<rbrakk> \<Longrightarrow> finite {u. a^u dvd y}" |
|
4005 apply(auto simp: dvd_def) |
|
4006 apply(rule_tac n = y in bounded_nat_set_is_finite, auto) |
|
4007 apply(case_tac k, simp,simp) |
|
4008 apply(rule_tac trans_less_add1) |
|
4009 apply(erule_tac x_less_exp) |
|
4010 done |
|
4011 |
|
4012 lemma conf_decode1: "\<lbrakk>m \<noteq> n; m \<noteq> k; k \<noteq> n\<rbrakk> \<Longrightarrow> |
|
4013 Max {u. Pi m ^ u dvd Pi m ^ l * Pi n ^ st * Pi k ^ r} = l" |
|
4014 proof - |
|
4015 let ?setx = "{u. Pi m ^ u dvd Pi m ^ l * Pi n ^ st * Pi k ^ r}" |
|
4016 assume g: "m \<noteq> n" "m \<noteq> k" "k \<noteq> n" |
|
4017 show "Max ?setx = l" |
|
4018 proof(rule_tac Max_eqI) |
|
4019 show "finite ?setx" |
|
4020 apply(rule_tac finite_power_dvd, auto simp: Pi_gr_1) |
|
4021 done |
|
4022 next |
|
4023 fix y |
|
4024 assume h: "y \<in> ?setx" |
|
4025 have "Pi m ^ y dvd Pi m ^ l" |
|
4026 proof - |
|
4027 have "Pi m ^ y dvd Pi m ^ l * Pi n ^ st" |
|
4028 using h g |
|
4029 apply(rule_tac n = "Pi k^r" in coprime_dvd_mult_nat) |
|
4030 apply(rule Pi_power_coprime, simp, simp) |
|
4031 done |
|
4032 thus "Pi m^y dvd Pi m^l" |
|
4033 apply(rule_tac n = " Pi n ^ st" in coprime_dvd_mult_nat) |
|
4034 using g |
|
4035 apply(rule_tac Pi_power_coprime, simp, simp) |
|
4036 done |
|
4037 qed |
|
4038 thus "y \<le> (l::nat)" |
|
4039 apply(rule_tac a = "Pi m" in power_le_imp_le_exp) |
|
4040 apply(simp_all add: Pi_gr_1) |
|
4041 apply(rule_tac dvd_power_le, auto) |
|
4042 done |
|
4043 next |
|
4044 show "l \<in> ?setx" by simp |
|
4045 qed |
|
4046 qed |
|
4047 |
|
4048 lemma conf_decode2: |
|
4049 "\<lbrakk>m \<noteq> n; m \<noteq> k; n \<noteq> k; |
|
4050 \<not> Suc 0 < Pi m ^ l * Pi n ^ st * Pi k ^ r\<rbrakk> \<Longrightarrow> l = 0" |
|
4051 apply(case_tac "Pi m ^ l * Pi n ^ st * Pi k ^ r", auto) |
|
4052 done |
|
4053 |
|
4054 lemma [simp]: "left (trpl l st r) = l" |
|
4055 apply(simp add: left.simps trpl.simps lo.simps |
|
4056 loR.simps mod_dvd_simp, auto simp: conf_decode1) |
|
4057 apply(case_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * Pi (Suc (Suc 0)) ^ r", |
|
4058 auto) |
|
4059 apply(erule_tac x = l in allE, auto) |
|
4060 done |
|
4061 |
|
4062 lemma [simp]: "stat (trpl l st r) = st" |
|
4063 apply(simp add: stat.simps trpl.simps lo.simps |
|
4064 loR.simps mod_dvd_simp, auto) |
|
4065 apply(subgoal_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * Pi (Suc (Suc 0)) ^ r |
|
4066 = Pi (Suc 0)^st * Pi 0 ^ l * Pi (Suc (Suc 0)) ^ r") |
|
4067 apply(simp (no_asm_simp) add: conf_decode1, simp) |
|
4068 apply(case_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * |
|
4069 Pi (Suc (Suc 0)) ^ r", auto) |
|
4070 apply(erule_tac x = st in allE, auto) |
|
4071 done |
|
4072 |
|
4073 lemma [simp]: "rght (trpl l st r) = r" |
|
4074 apply(simp add: rght.simps trpl.simps lo.simps |
|
4075 loR.simps mod_dvd_simp, auto) |
|
4076 apply(subgoal_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * Pi (Suc (Suc 0)) ^ r |
|
4077 = Pi (Suc (Suc 0))^r * Pi 0 ^ l * Pi (Suc 0) ^ st") |
|
4078 apply(simp (no_asm_simp) add: conf_decode1, simp) |
|
4079 apply(case_tac "Pi 0 ^ l * Pi (Suc 0) ^ st * Pi (Suc (Suc 0)) ^ r", |
|
4080 auto) |
|
4081 apply(erule_tac x = r in allE, auto) |
|
4082 done |
|
4083 |
|
4084 lemma max_lor: |
|
4085 "i < length nl \<Longrightarrow> Max {u. loR [godel_code nl, Pi (Suc i), u]} |
|
4086 = nl ! i" |
|
4087 apply(simp add: loR.simps godel_code_get_nth mod_dvd_simp) |
|
4088 done |
|
4089 |
|
4090 lemma godel_decode: |
|
4091 "i < length nl \<Longrightarrow> Entry (godel_code nl) i = nl ! i" |
|
4092 apply(auto simp: Entry.simps lo.simps max_lor) |
|
4093 apply(erule_tac x = "nl!i" in allE) |
|
4094 using max_lor[of i nl] godel_finite[of i nl] |
|
4095 apply(simp) |
|
4096 apply(drule_tac Max_in, auto simp: loR.simps |
|
4097 godel_code.simps mod_dvd_simp) |
|
4098 using godel_code_in[of i nl] |
|
4099 apply(simp) |
|
4100 done |
|
4101 |
|
4102 lemma Four_Suc: "4 = Suc (Suc (Suc (Suc 0)))" |
|
4103 by auto |
|
4104 |
|
4105 declare numeral_2_eq_2[simp del] |
|
4106 |
|
4107 lemma modify_tprog_fetch_even: |
|
4108 "\<lbrakk>st \<le> length tp div 2; st > 0\<rbrakk> \<Longrightarrow> |
|
4109 modify_tprog tp ! (4 * (st - Suc 0) ) = |
|
4110 action_map (fst (tp ! (2 * (st - Suc 0))))" |
|
4111 proof(induct st arbitrary: tp, simp) |
|
4112 fix tp st |
|
4113 assume ind: |
|
4114 "\<And>tp. \<lbrakk>st \<le> length tp div 2; 0 < st\<rbrakk> \<Longrightarrow> |
|
4115 modify_tprog tp ! (4 * (st - Suc 0)) = |
|
4116 action_map (fst ((tp::tprog) ! (2 * (st - Suc 0))))" |
|
4117 and h: "Suc st \<le> length (tp::tprog) div 2" "0 < Suc st" |
|
4118 thus "modify_tprog tp ! (4 * (Suc st - Suc 0)) = |
|
4119 action_map (fst (tp ! (2 * (Suc st - Suc 0))))" |
|
4120 proof(cases "st = 0") |
|
4121 case True thus "?thesis" |
|
4122 using h |
|
4123 apply(auto) |
|
4124 apply(cases tp, simp, case_tac a, simp add: modify_tprog.simps) |
|
4125 done |
|
4126 next |
|
4127 case False |
|
4128 assume g: "st \<noteq> 0" |
|
4129 hence "\<exists> aa ab ba bb tp'. tp = (aa, ab) # (ba, bb) # tp'" |
|
4130 using h |
|
4131 apply(case_tac tp, simp, case_tac list, simp, simp) |
|
4132 done |
|
4133 from this obtain aa ab ba bb tp' where g1: |
|
4134 "tp = (aa, ab) # (ba, bb) # tp'" by blast |
|
4135 hence g2: |
|
4136 "modify_tprog tp' ! (4 * (st - Suc 0)) = |
|
4137 action_map (fst ((tp'::tprog) ! (2 * (st - Suc 0))))" |
|
4138 apply(rule_tac ind) |
|
4139 using h g by auto |
|
4140 thus "?thesis" |
|
4141 using g1 g |
|
4142 apply(case_tac st, simp, simp add: Four_Suc) |
|
4143 done |
|
4144 qed |
|
4145 qed |
|
4146 |
|
4147 lemma modify_tprog_fetch_odd: |
|
4148 "\<lbrakk>st \<le> length tp div 2; st > 0\<rbrakk> \<Longrightarrow> |
|
4149 modify_tprog tp ! (Suc (Suc (4 * (st - Suc 0)))) = |
|
4150 action_map (fst (tp ! (Suc (2 * (st - Suc 0)))))" |
|
4151 proof(induct st arbitrary: tp, simp) |
|
4152 fix tp st |
|
4153 assume ind: |
|
4154 "\<And>tp. \<lbrakk>st \<le> length tp div 2; 0 < st\<rbrakk> \<Longrightarrow> |
|
4155 modify_tprog tp ! Suc (Suc (4 * (st - Suc 0))) = |
|
4156 action_map (fst (tp ! Suc (2 * (st - Suc 0))))" |
|
4157 and h: "Suc st \<le> length (tp::tprog) div 2" "0 < Suc st" |
|
4158 thus "modify_tprog tp ! Suc (Suc (4 * (Suc st - Suc 0))) |
|
4159 = action_map (fst (tp ! Suc (2 * (Suc st - Suc 0))))" |
|
4160 proof(cases "st = 0") |
|
4161 case True thus "?thesis" |
|
4162 using h |
|
4163 apply(auto) |
|
4164 apply(cases tp, simp, case_tac a, simp add: modify_tprog.simps) |
|
4165 apply(case_tac list, simp, case_tac ab, |
|
4166 simp add: modify_tprog.simps) |
|
4167 done |
|
4168 next |
|
4169 case False |
|
4170 assume g: "st \<noteq> 0" |
|
4171 hence "\<exists> aa ab ba bb tp'. tp = (aa, ab) # (ba, bb) # tp'" |
|
4172 using h |
|
4173 apply(case_tac tp, simp, case_tac list, simp, simp) |
|
4174 done |
|
4175 from this obtain aa ab ba bb tp' where g1: |
|
4176 "tp = (aa, ab) # (ba, bb) # tp'" by blast |
|
4177 hence g2: "modify_tprog tp' ! Suc (Suc (4 * (st - Suc 0))) = |
|
4178 action_map (fst (tp' ! Suc (2 * (st - Suc 0))))" |
|
4179 apply(rule_tac ind) |
|
4180 using h g by auto |
|
4181 thus "?thesis" |
|
4182 using g1 g |
|
4183 apply(case_tac st, simp, simp add: Four_Suc) |
|
4184 done |
|
4185 qed |
|
4186 qed |
|
4187 |
|
4188 lemma modify_tprog_fetch_action: |
|
4189 "\<lbrakk>st \<le> length tp div 2; st > 0; b = 1 \<or> b = 0\<rbrakk> \<Longrightarrow> |
|
4190 modify_tprog tp ! (4 * (st - Suc 0) + 2* b) = |
|
4191 action_map (fst (tp ! ((2 * (st - Suc 0)) + b)))" |
|
4192 apply(erule_tac disjE, auto elim: modify_tprog_fetch_odd |
|
4193 modify_tprog_fetch_even) |
|
4194 done |
|
4195 |
|
4196 lemma length_modify: "length (modify_tprog tp) = 2 * length tp" |
|
4197 apply(induct tp, auto) |
|
4198 done |
|
4199 |
|
4200 declare fetch.simps[simp del] |
|
4201 |
|
4202 lemma fetch_action_eq: |
|
4203 "\<lbrakk>block_map b = scan r; fetch tp st b = (nact, ns); |
|
4204 st \<le> length tp div 2\<rbrakk> \<Longrightarrow> actn (code tp) st r = action_map nact" |
|
4205 proof(simp add: actn.simps, auto) |
|
4206 let ?i = "4 * (st - Suc 0) + 2 * (r mod 2)" |
|
4207 assume h: "block_map b = r mod 2" "fetch tp st b = (nact, ns)" |
|
4208 "st \<le> length tp div 2" "0 < st" |
|
4209 have "?i < length (modify_tprog tp)" |
|
4210 proof - |
|
4211 have "length (modify_tprog tp) = 2 * length tp" |
|
4212 by(simp add: length_modify) |
|
4213 thus "?thesis" |
|
4214 using h |
|
4215 by(auto) |
|
4216 qed |
|
4217 hence |
|
4218 "Entry (godel_code (modify_tprog tp))?i = |
|
4219 (modify_tprog tp) ! ?i" |
|
4220 by(erule_tac godel_decode) |
|
4221 thm modify_tprog.simps |
|
4222 moreover have |
|
4223 "modify_tprog tp ! ?i = |
|
4224 action_map (fst (tp ! (2 * (st - Suc 0) + r mod 2)))" |
|
4225 apply(rule_tac modify_tprog_fetch_action) |
|
4226 using h |
|
4227 by(auto) |
|
4228 moreover have "(fst (tp ! (2 * (st - Suc 0) + r mod 2))) = nact" |
|
4229 using h |
|
4230 apply(simp add: fetch.simps nth_of.simps) |
|
4231 apply(case_tac b, auto simp: block_map.simps nth_of.simps split: if_splits) |
|
4232 done |
|
4233 ultimately show |
|
4234 "Entry (godel_code (modify_tprog tp)) |
|
4235 (4 * (st - Suc 0) + 2 * (r mod 2)) |
|
4236 = action_map nact" |
|
4237 by simp |
|
4238 qed |
|
4239 |
|
4240 lemma [simp]: "fetch tp 0 b = (nact, ns) \<Longrightarrow> ns = 0" |
|
4241 by(simp add: fetch.simps) |
|
4242 |
|
4243 lemma Five_Suc: "5 = Suc 4" by simp |
|
4244 |
|
4245 lemma modify_tprog_fetch_state: |
|
4246 "\<lbrakk>st \<le> length tp div 2; st > 0; b = 1 \<or> b = 0\<rbrakk> \<Longrightarrow> |
|
4247 modify_tprog tp ! Suc (4 * (st - Suc 0) + 2 * b) = |
|
4248 (snd (tp ! (2 * (st - Suc 0) + b)))" |
|
4249 proof(induct st arbitrary: tp, simp) |
|
4250 fix st tp |
|
4251 assume ind: |
|
4252 "\<And>tp. \<lbrakk>st \<le> length tp div 2; 0 < st; b = 1 \<or> b = 0\<rbrakk> \<Longrightarrow> |
|
4253 modify_tprog tp ! Suc (4 * (st - Suc 0) + 2 * b) = |
|
4254 snd (tp ! (2 * (st - Suc 0) + b))" |
|
4255 and h: |
|
4256 "Suc st \<le> length (tp::tprog) div 2" |
|
4257 "0 < Suc st" |
|
4258 "b = 1 \<or> b = 0" |
|
4259 show "modify_tprog tp ! Suc (4 * (Suc st - Suc 0) + 2 * b) = |
|
4260 snd (tp ! (2 * (Suc st - Suc 0) + b))" |
|
4261 proof(cases "st = 0") |
|
4262 case True |
|
4263 thus "?thesis" |
|
4264 using h |
|
4265 apply(cases tp, simp, case_tac a, simp add: modify_tprog.simps) |
|
4266 apply(case_tac list, simp, case_tac ab, |
|
4267 simp add: modify_tprog.simps, auto) |
|
4268 done |
|
4269 next |
|
4270 case False |
|
4271 assume g: "st \<noteq> 0" |
|
4272 hence "\<exists> aa ab ba bb tp'. tp = (aa, ab) # (ba, bb) # tp'" |
|
4273 using h |
|
4274 apply(case_tac tp, simp, case_tac list, simp, simp) |
|
4275 done |
|
4276 from this obtain aa ab ba bb tp' where g1: |
|
4277 "tp = (aa, ab) # (ba, bb) # tp'" by blast |
|
4278 hence g2: |
|
4279 "modify_tprog tp' ! Suc (4 * (st - Suc 0) + 2 * b) = |
|
4280 snd (tp' ! (2 * (st - Suc 0) + b))" |
|
4281 apply(rule_tac ind) |
|
4282 using h g by auto |
|
4283 thus "?thesis" |
|
4284 using g1 g |
|
4285 apply(case_tac st, simp, simp) |
|
4286 done |
|
4287 qed |
|
4288 qed |
|
4289 |
|
4290 lemma fetch_state_eq: |
|
4291 "\<lbrakk>block_map b = scan r; |
|
4292 fetch tp st b = (nact, ns); |
|
4293 st \<le> length tp div 2\<rbrakk> \<Longrightarrow> newstat (code tp) st r = ns" |
|
4294 proof(simp add: newstat.simps, auto) |
|
4295 let ?i = "Suc (4 * (st - Suc 0) + 2 * (r mod 2))" |
|
4296 assume h: "block_map b = r mod 2" "fetch tp st b = |
|
4297 (nact, ns)" "st \<le> length tp div 2" "0 < st" |
|
4298 have "?i < length (modify_tprog tp)" |
|
4299 proof - |
|
4300 have "length (modify_tprog tp) = 2 * length tp" |
|
4301 apply(simp add: length_modify) |
|
4302 done |
|
4303 thus "?thesis" |
|
4304 using h |
|
4305 by(auto) |
|
4306 qed |
|
4307 hence "Entry (godel_code (modify_tprog tp)) (?i) = |
|
4308 (modify_tprog tp) ! ?i" |
|
4309 by(erule_tac godel_decode) |
|
4310 thm modify_tprog.simps |
|
4311 moreover have |
|
4312 "modify_tprog tp ! ?i = |
|
4313 (snd (tp ! (2 * (st - Suc 0) + r mod 2)))" |
|
4314 apply(rule_tac modify_tprog_fetch_state) |
|
4315 using h |
|
4316 by(auto) |
|
4317 moreover have "(snd (tp ! (2 * (st - Suc 0) + r mod 2))) = ns" |
|
4318 using h |
|
4319 apply(simp add: fetch.simps nth_of.simps) |
|
4320 apply(case_tac b, auto simp: block_map.simps nth_of.simps |
|
4321 split: if_splits) |
|
4322 done |
|
4323 ultimately show "Entry (godel_code (modify_tprog tp)) (?i) |
|
4324 = ns" |
|
4325 by simp |
|
4326 qed |
|
4327 |
|
4328 |
|
4329 lemma [intro!]: |
|
4330 "\<lbrakk>a = a'; b = b'; c = c'\<rbrakk> \<Longrightarrow> trpl a b c = trpl a' b' c'" |
|
4331 by simp |
|
4332 |
|
4333 lemma [simp]: "bl2wc [Bk] = 0" |
|
4334 by(simp add: bl2wc.simps bl2nat.simps) |
|
4335 |
|
4336 lemma bl2nat_double: "bl2nat xs (Suc n) = 2 * bl2nat xs n" |
|
4337 proof(induct xs arbitrary: n) |
|
4338 case Nil thus "?case" |
|
4339 by(simp add: bl2nat.simps) |
|
4340 next |
|
4341 case (Cons x xs) thus "?case" |
|
4342 proof - |
|
4343 assume ind: "\<And>n. bl2nat xs (Suc n) = 2 * bl2nat xs n " |
|
4344 show "bl2nat (x # xs) (Suc n) = 2 * bl2nat (x # xs) n" |
|
4345 proof(cases x) |
|
4346 case Bk thus "?thesis" |
|
4347 apply(simp add: bl2nat.simps) |
|
4348 using ind[of "Suc n"] by simp |
|
4349 next |
|
4350 case Oc thus "?thesis" |
|
4351 apply(simp add: bl2nat.simps) |
|
4352 using ind[of "Suc n"] by simp |
|
4353 qed |
|
4354 qed |
|
4355 qed |
|
4356 |
|
4357 |
|
4358 lemma [simp]: "c \<noteq> [] \<Longrightarrow> 2 * bl2wc (tl c) = bl2wc c - bl2wc c mod 2 " |
|
4359 apply(case_tac c, simp, case_tac a) |
|
4360 apply(auto simp: bl2wc.simps bl2nat.simps bl2nat_double) |
|
4361 done |
|
4362 |
|
4363 lemma [simp]: |
|
4364 "c \<noteq> [] \<Longrightarrow> bl2wc (Oc # tl c) = Suc (bl2wc c) - bl2wc c mod 2 " |
|
4365 apply(case_tac c, simp, case_tac a) |
|
4366 apply(auto simp: bl2wc.simps bl2nat.simps bl2nat_double) |
|
4367 done |
|
4368 |
|
4369 lemma [simp]: "bl2wc (Bk # c) = 2*bl2wc (c)" |
|
4370 apply(simp add: bl2wc.simps bl2nat.simps bl2nat_double) |
|
4371 done |
|
4372 |
|
4373 lemma [simp]: "bl2wc [Oc] = Suc 0" |
|
4374 by(simp add: bl2wc.simps bl2nat.simps) |
|
4375 |
|
4376 lemma [simp]: "b \<noteq> [] \<Longrightarrow> bl2wc (tl b) = bl2wc b div 2" |
|
4377 apply(case_tac b, simp, case_tac a) |
|
4378 apply(auto simp: bl2wc.simps bl2nat.simps bl2nat_double) |
|
4379 done |
|
4380 |
|
4381 lemma [simp]: "b \<noteq> [] \<Longrightarrow> bl2wc ([hd b]) = bl2wc b mod 2" |
|
4382 apply(case_tac b, simp, case_tac a) |
|
4383 apply(auto simp: bl2wc.simps bl2nat.simps bl2nat_double) |
|
4384 done |
|
4385 |
|
4386 lemma [simp]: "\<lbrakk>b \<noteq> []; c \<noteq> []\<rbrakk> \<Longrightarrow> bl2wc (hd b # c) = 2 * bl2wc c + bl2wc b mod 2" |
|
4387 apply(case_tac b, simp, case_tac a) |
|
4388 apply(auto simp: bl2wc.simps bl2nat.simps bl2nat_double) |
|
4389 done |
|
4390 |
|
4391 lemma [simp]: " 2 * (bl2wc c div 2) = bl2wc c - bl2wc c mod 2" |
|
4392 by(simp add: mult_div_cancel) |
|
4393 |
|
4394 lemma [simp]: "bl2wc (Oc # list) mod 2 = Suc 0" |
|
4395 by(simp add: bl2wc.simps bl2nat.simps bl2nat_double) |
|
4396 |
|
4397 |
|
4398 declare code.simps[simp del] |
|
4399 declare nth_of.simps[simp del] |
|
4400 declare new_tape.simps[simp del] |
|
4401 |
|
4402 text {* |
|
4403 The lemma relates the one step execution of TMs with the interpreter function @{text "rec_newconf"}. |
|
4404 *} |
|
4405 lemma rec_t_eq_step: |
|
4406 "(\<lambda> (s, l, r). s \<le> length tp div 2) c \<Longrightarrow> |
|
4407 trpl_code (tstep c tp) = |
|
4408 rec_exec rec_newconf [code tp, trpl_code c]" |
|
4409 apply(cases c, auto simp: tstep.simps) |
|
4410 proof(case_tac "fetch tp a (case c of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x)", |
|
4411 simp add: newconf.simps trpl_code.simps) |
|
4412 fix a b c aa ba |
|
4413 assume h: "(a::nat) \<le> length tp div 2" |
|
4414 "fetch tp a (case c of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x) = (aa, ba)" |
|
4415 moreover hence "actn (code tp) a (bl2wc c) = action_map aa" |
|
4416 apply(rule_tac b = "(case c of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x)" |
|
4417 in fetch_action_eq, auto) |
|
4418 apply(auto split: list.splits) |
|
4419 apply(case_tac ab, auto) |
|
4420 done |
|
4421 moreover from h have "(newstat (code tp) a (bl2wc c)) = ba" |
|
4422 apply(rule_tac b = "(case c of [] \<Rightarrow> Bk | x # xs \<Rightarrow> x)" |
|
4423 in fetch_state_eq, auto split: list.splits) |
|
4424 apply(case_tac ab, auto) |
|
4425 done |
|
4426 ultimately show |
|
4427 "trpl_code (ba, new_tape aa (b, c)) = |
|
4428 trpl (newleft (bl2wc b) (bl2wc c) (actn (code tp) a (bl2wc c))) |
|
4429 (newstat (code tp) a (bl2wc c)) (newrght (bl2wc b) (bl2wc c) |
|
4430 (actn (code tp) a (bl2wc c)))" |
|
4431 by(auto simp: new_tape.simps trpl_code.simps |
|
4432 newleft.simps newrght.simps split: taction.splits) |
|
4433 qed |
|
4434 |
|
4435 lemma [simp]: "a\<^bsup>0\<^esup> = []" |
|
4436 apply(simp add: exp_zero) |
|
4437 done |
|
4438 lemma [simp]: "bl2nat (Oc # Oc\<^bsup>x\<^esup>) 0 = (2 * 2 ^ x - Suc 0)" |
|
4439 apply(induct x) |
|
4440 apply(simp add: bl2nat.simps) |
|
4441 apply(simp add: bl2nat.simps bl2nat_double exp_ind_def) |
|
4442 done |
|
4443 |
|
4444 lemma [simp]: "bl2nat (Oc\<^bsup>y\<^esup>) 0 = 2^y - Suc 0" |
|
4445 apply(induct y, auto simp: bl2nat.simps exp_ind_def bl2nat_double) |
|
4446 apply(case_tac "(2::nat)^y", auto) |
|
4447 done |
|
4448 |
|
4449 lemma [simp]: "bl2nat (Bk\<^bsup>l\<^esup>) n = 0" |
|
4450 apply(induct l, auto simp: bl2nat.simps bl2nat_double exp_ind_def) |
|
4451 done |
|
4452 |
|
4453 lemma bl2nat_cons_bk: "bl2nat (ks @ [Bk]) 0 = bl2nat ks 0" |
|
4454 apply(induct ks, auto simp: bl2nat.simps split: block.splits) |
|
4455 apply(case_tac a, auto simp: bl2nat.simps bl2nat_double) |
|
4456 done |
|
4457 |
|
4458 lemma bl2nat_cons_oc: |
|
4459 "bl2nat (ks @ [Oc]) 0 = bl2nat ks 0 + 2 ^ length ks" |
|
4460 apply(induct ks, auto simp: bl2nat.simps split: block.splits) |
|
4461 apply(case_tac a, auto simp: bl2nat.simps bl2nat_double) |
|
4462 done |
|
4463 |
|
4464 lemma bl2nat_append: |
|
4465 "bl2nat (xs @ ys) 0 = bl2nat xs 0 + bl2nat ys (length xs) " |
|
4466 proof(induct "length xs" arbitrary: xs ys, simp add: bl2nat.simps) |
|
4467 fix x xs ys |
|
4468 assume ind: |
|
4469 "\<And>xs ys. x = length xs \<Longrightarrow> |
|
4470 bl2nat (xs @ ys) 0 = bl2nat xs 0 + bl2nat ys (length xs)" |
|
4471 and h: "Suc x = length (xs::block list)" |
|
4472 have "\<exists> ks k. xs = ks @ [k]" |
|
4473 apply(rule_tac x = "butlast xs" in exI, |
|
4474 rule_tac x = "last xs" in exI) |
|
4475 using h |
|
4476 apply(case_tac xs, auto) |
|
4477 done |
|
4478 from this obtain ks k where "xs = ks @ [k]" by blast |
|
4479 moreover hence |
|
4480 "bl2nat (ks @ (k # ys)) 0 = bl2nat ks 0 + |
|
4481 bl2nat (k # ys) (length ks)" |
|
4482 apply(rule_tac ind) using h by simp |
|
4483 ultimately show "bl2nat (xs @ ys) 0 = |
|
4484 bl2nat xs 0 + bl2nat ys (length xs)" |
|
4485 apply(case_tac k, simp_all add: bl2nat.simps) |
|
4486 apply(simp_all only: bl2nat_cons_bk bl2nat_cons_oc) |
|
4487 done |
|
4488 qed |
|
4489 |
|
4490 lemma bl2nat_exp: "n \<noteq> 0 \<Longrightarrow> bl2nat bl n = 2^n * bl2nat bl 0" |
|
4491 apply(induct bl) |
|
4492 apply(auto simp: bl2nat.simps) |
|
4493 apply(case_tac a, auto simp: bl2nat.simps bl2nat_double) |
|
4494 done |
|
4495 |
|
4496 lemma nat_minus_eq: "\<lbrakk>a = b; c = d\<rbrakk> \<Longrightarrow> a - c = b - d" |
|
4497 by auto |
|
4498 |
|
4499 lemma tape_of_nat_list_butlast_last: |
|
4500 "ys \<noteq> [] \<Longrightarrow> <ys @ [y]> = <ys> @ Bk # Oc\<^bsup>Suc y\<^esup>" |
|
4501 apply(induct ys, simp, simp) |
|
4502 apply(case_tac "ys = []", simp add: tape_of_nl_abv |
|
4503 tape_of_nat_list.simps) |
|
4504 apply(simp) |
|
4505 done |
|
4506 |
|
4507 lemma listsum2_append: |
|
4508 "\<lbrakk>n \<le> length xs\<rbrakk> \<Longrightarrow> listsum2 (xs @ ys) n = listsum2 xs n" |
|
4509 apply(induct n) |
|
4510 apply(auto simp: listsum2.simps nth_append) |
|
4511 done |
|
4512 |
|
4513 lemma strt'_append: |
|
4514 "\<lbrakk>n \<le> length xs\<rbrakk> \<Longrightarrow> strt' xs n = strt' (xs @ ys) n" |
|
4515 proof(induct n arbitrary: xs ys) |
|
4516 fix xs ys |
|
4517 show "strt' xs 0 = strt' (xs @ ys) 0" by(simp add: strt'.simps) |
|
4518 next |
|
4519 fix n xs ys |
|
4520 assume ind: |
|
4521 "\<And> xs ys. n \<le> length xs \<Longrightarrow> strt' xs n = strt' (xs @ ys) n" |
|
4522 and h: "Suc n \<le> length (xs::nat list)" |
|
4523 show "strt' xs (Suc n) = strt' (xs @ ys) (Suc n)" |
|
4524 using ind[of xs ys] h |
|
4525 apply(simp add: strt'.simps nth_append listsum2_append) |
|
4526 done |
|
4527 qed |
|
4528 |
|
4529 lemma length_listsum2_eq: |
|
4530 "\<lbrakk>length (ys::nat list) = k\<rbrakk> |
|
4531 \<Longrightarrow> length (<ys>) = listsum2 (map Suc ys) k + k - 1" |
|
4532 apply(induct k arbitrary: ys, simp_all add: listsum2.simps) |
|
4533 apply(subgoal_tac "\<exists> xs x. ys = xs @ [x]", auto) |
|
4534 proof - |
|
4535 fix xs x |
|
4536 assume ind: "\<And>ys. length ys = length xs \<Longrightarrow> length (<ys>) |
|
4537 = listsum2 (map Suc ys) (length xs) + |
|
4538 length (xs::nat list) - Suc 0" |
|
4539 have "length (<xs>) |
|
4540 = listsum2 (map Suc xs) (length xs) + length xs - Suc 0" |
|
4541 apply(rule_tac ind, simp) |
|
4542 done |
|
4543 thus "length (<xs @ [x]>) = |
|
4544 Suc (listsum2 (map Suc xs @ [Suc x]) (length xs) + x + length xs)" |
|
4545 apply(case_tac "xs = []") |
|
4546 apply(simp add: tape_of_nl_abv listsum2.simps |
|
4547 tape_of_nat_list.simps) |
|
4548 apply(simp add: tape_of_nat_list_butlast_last) |
|
4549 using listsum2_append[of "length xs" "map Suc xs" "[Suc x]"] |
|
4550 apply(simp) |
|
4551 done |
|
4552 next |
|
4553 fix k ys |
|
4554 assume "length ys = Suc k" |
|
4555 thus "\<exists>xs x. ys = xs @ [x]" |
|
4556 apply(rule_tac x = "butlast ys" in exI, |
|
4557 rule_tac x = "last ys" in exI) |
|
4558 apply(case_tac ys, auto) |
|
4559 done |
|
4560 qed |
|
4561 |
|
4562 lemma tape_of_nat_list_length: |
|
4563 "length (<(ys::nat list)>) = |
|
4564 listsum2 (map Suc ys) (length ys) + length ys - 1" |
|
4565 using length_listsum2_eq[of ys "length ys"] |
|
4566 apply(simp) |
|
4567 done |
|
4568 |
|
4569 |
|
4570 |
|
4571 lemma [simp]: |
|
4572 "trpl_code (steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp 0) = |
|
4573 rec_exec rec_conf [code tp, bl2wc (<lm>), 0]" |
|
4574 apply(simp add: steps.simps rec_exec.simps conf_lemma conf.simps |
|
4575 inpt.simps trpl_code.simps bl2wc.simps) |
|
4576 done |
|
4577 |
|
4578 text {* |
|
4579 The following lemma relates the multi-step interpreter function @{text "rec_conf"} |
|
4580 with the multi-step execution of TMs. |
|
4581 *} |
|
4582 lemma rec_t_eq_steps: |
|
4583 "turing_basic.t_correct tp \<Longrightarrow> |
|
4584 trpl_code (steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp) = |
|
4585 rec_exec rec_conf [code tp, bl2wc (<lm>), stp]" |
|
4586 proof(induct stp) |
|
4587 case 0 thus "?case" by(simp) |
|
4588 next |
|
4589 case (Suc n) thus "?case" |
|
4590 proof - |
|
4591 assume ind: |
|
4592 "t_correct tp \<Longrightarrow> trpl_code (steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp n) |
|
4593 = rec_exec rec_conf [code tp, bl2wc (<lm>), n]" |
|
4594 and h: "t_correct tp" |
|
4595 show |
|
4596 "trpl_code (steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp (Suc n)) = |
|
4597 rec_exec rec_conf [code tp, bl2wc (<lm>), Suc n]" |
|
4598 proof(case_tac "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp n", |
|
4599 simp only: tstep_red conf_lemma conf.simps) |
|
4600 fix a b c |
|
4601 assume g: "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp n = (a, b, c) " |
|
4602 hence "conf (code tp) (bl2wc (<lm>)) n= trpl_code (a, b, c)" |
|
4603 using ind h |
|
4604 apply(simp add: conf_lemma) |
|
4605 done |
|
4606 moreover hence |
|
4607 "trpl_code (tstep (a, b, c) tp) = |
|
4608 rec_exec rec_newconf [code tp, trpl_code (a, b, c)]" |
|
4609 thm rec_t_eq_step |
|
4610 apply(rule_tac rec_t_eq_step) |
|
4611 using h g |
|
4612 apply(simp add: s_keep) |
|
4613 done |
|
4614 ultimately show |
|
4615 "trpl_code (tstep (a, b, c) tp) = |
|
4616 newconf (code tp) (conf (code tp) (bl2wc (<lm>)) n)" |
|
4617 by(simp add: newconf_lemma) |
|
4618 qed |
|
4619 qed |
|
4620 qed |
|
4621 |
|
4622 lemma [simp]: "bl2wc (Bk\<^bsup>m\<^esup>) = 0" |
|
4623 apply(induct m) |
|
4624 apply(simp, simp) |
|
4625 done |
|
4626 |
|
4627 lemma [simp]: "bl2wc (Oc\<^bsup>rs\<^esup>@Bk\<^bsup>n\<^esup>) = bl2wc (Oc\<^bsup>rs\<^esup>)" |
|
4628 apply(induct rs, simp, |
|
4629 simp add: bl2wc.simps bl2nat.simps bl2nat_double) |
|
4630 done |
|
4631 |
|
4632 lemma lg_power: "x > Suc 0 \<Longrightarrow> lg (x ^ rs) x = rs" |
|
4633 proof(simp add: lg.simps, auto) |
|
4634 fix xa |
|
4635 assume h: "Suc 0 < x" |
|
4636 show "Max {ya. ya \<le> x ^ rs \<and> lgR [x ^ rs, x, ya]} = rs" |
|
4637 apply(rule_tac Max_eqI, simp_all add: lgR.simps) |
|
4638 apply(simp add: h) |
|
4639 using x_less_exp[of x rs] h |
|
4640 apply(simp) |
|
4641 done |
|
4642 next |
|
4643 assume "\<not> Suc 0 < x ^ rs" "Suc 0 < x" |
|
4644 thus "rs = 0" |
|
4645 apply(case_tac "x ^ rs", simp, simp) |
|
4646 done |
|
4647 next |
|
4648 assume "Suc 0 < x" "\<forall>xa. \<not> lgR [x ^ rs, x, xa]" |
|
4649 thus "rs = 0" |
|
4650 apply(simp only:lgR.simps) |
|
4651 apply(erule_tac x = rs in allE, simp) |
|
4652 done |
|
4653 qed |
|
4654 |
|
4655 text {* |
|
4656 The following lemma relates execution of TMs with |
|
4657 the multi-step interpreter function @{text "rec_nonstop"}. Note, |
|
4658 @{text "rec_nonstop"} is constructed using @{text "rec_conf"}. |
|
4659 *} |
|
4660 lemma nonstop_t_eq: |
|
4661 "\<lbrakk>steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>); |
|
4662 turing_basic.t_correct tp; |
|
4663 rs > 0\<rbrakk> |
|
4664 \<Longrightarrow> rec_exec rec_nonstop [code tp, bl2wc (<lm>), stp] = 0" |
|
4665 proof(simp add: nonstop_lemma nonstop.simps nstd.simps) |
|
4666 assume h: "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)" |
|
4667 and tc_t: "turing_basic.t_correct tp" "rs > 0" |
|
4668 have g: "rec_exec rec_conf [code tp, bl2wc (<lm>), stp] = |
|
4669 trpl_code (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup>@Bk\<^bsup>n\<^esup>)" |
|
4670 using rec_t_eq_steps[of tp l lm stp] tc_t h |
|
4671 by(simp) |
|
4672 thus "\<not> NSTD (conf (code tp) (bl2wc (<lm>)) stp)" |
|
4673 proof(auto simp: NSTD.simps) |
|
4674 show "stat (conf (code tp) (bl2wc (<lm>)) stp) = 0" |
|
4675 using g |
|
4676 by(auto simp: conf_lemma trpl_code.simps) |
|
4677 next |
|
4678 show "left (conf (code tp) (bl2wc (<lm>)) stp) = 0" |
|
4679 using g |
|
4680 by(simp add: conf_lemma trpl_code.simps) |
|
4681 next |
|
4682 show "rght (conf (code tp) (bl2wc (<lm>)) stp) = |
|
4683 2 ^ lg (Suc (rght (conf (code tp) (bl2wc (<lm>)) stp))) 2 - Suc 0" |
|
4684 using g h |
|
4685 proof(simp add: conf_lemma trpl_code.simps) |
|
4686 have "2 ^ lg (Suc (bl2wc (Oc\<^bsup>rs\<^esup>))) 2 = Suc (bl2wc (Oc\<^bsup>rs\<^esup>))" |
|
4687 apply(simp add: bl2wc.simps lg_power) |
|
4688 done |
|
4689 thus "bl2wc (Oc\<^bsup>rs\<^esup>) = 2 ^ lg (Suc (bl2wc (Oc\<^bsup>rs\<^esup>))) 2 - Suc 0" |
|
4690 apply(simp) |
|
4691 done |
|
4692 qed |
|
4693 next |
|
4694 show "0 < rght (conf (code tp) (bl2wc (<lm>)) stp)" |
|
4695 using g h tc_t |
|
4696 apply(simp add: conf_lemma trpl_code.simps bl2wc.simps |
|
4697 bl2nat.simps) |
|
4698 apply(case_tac rs, simp, simp add: bl2nat.simps) |
|
4699 done |
|
4700 qed |
|
4701 qed |
|
4702 |
|
4703 lemma [simp]: "actn m 0 r = 4" |
|
4704 by(simp add: actn.simps) |
|
4705 |
|
4706 lemma [simp]: "newstat m 0 r = 0" |
|
4707 by(simp add: newstat.simps) |
|
4708 |
|
4709 declare exp_def[simp del] |
|
4710 |
|
4711 lemma halt_least_step: |
|
4712 "\<lbrakk>steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs \<^esup> @ Bk\<^bsup>n\<^esup>); |
|
4713 turing_basic.t_correct tp; |
|
4714 0<rs\<rbrakk> \<Longrightarrow> |
|
4715 \<exists> stp. (nonstop (code tp) (bl2wc (<lm>)) stp = 0 \<and> |
|
4716 (\<forall> stp'. nonstop (code tp) (bl2wc (<lm>)) stp' = 0 \<longrightarrow> stp \<le> stp'))" |
|
4717 proof(induct stp, simp add: steps.simps, simp) |
|
4718 fix stp |
|
4719 assume ind: |
|
4720 "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>) \<Longrightarrow> |
|
4721 \<exists>stp. nonstop (code tp) (bl2wc (<lm>)) stp = 0 \<and> |
|
4722 (\<forall>stp'. nonstop (code tp) (bl2wc (<lm>)) stp' = 0 \<longrightarrow> stp \<le> stp')" |
|
4723 and h: |
|
4724 "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp (Suc stp) = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)" |
|
4725 "turing_basic.t_correct tp" |
|
4726 "0 < rs" |
|
4727 from h show |
|
4728 "\<exists>stp. nonstop (code tp) (bl2wc (<lm>)) stp = 0 |
|
4729 \<and> (\<forall>stp'. nonstop (code tp) (bl2wc (<lm>)) stp' = 0 \<longrightarrow> stp \<le> stp')" |
|
4730 proof(simp add: tstep_red, |
|
4731 case_tac "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp", simp, |
|
4732 case_tac a, simp add: tstep_0) |
|
4733 assume "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)" |
|
4734 thus "\<exists>stp. nonstop (code tp) (bl2wc (<lm>)) stp = 0 \<and> |
|
4735 (\<forall>stp'. nonstop (code tp) (bl2wc (<lm>)) stp' = 0 \<longrightarrow> stp \<le> stp')" |
|
4736 apply(erule_tac ind) |
|
4737 done |
|
4738 next |
|
4739 fix a b c nat |
|
4740 assume "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (a, b, c)" |
|
4741 "a = Suc nat" |
|
4742 thus "\<exists>stp. nonstop (code tp) (bl2wc (<lm>)) stp = 0 \<and> |
|
4743 (\<forall>stp'. nonstop (code tp) (bl2wc (<lm>)) stp' = 0 \<longrightarrow> stp \<le> stp')" |
|
4744 using h |
|
4745 apply(rule_tac x = "Suc stp" in exI, auto) |
|
4746 apply(drule_tac nonstop_t_eq, simp_all add: nonstop_lemma) |
|
4747 proof - |
|
4748 fix stp' |
|
4749 assume g:"steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (Suc nat, b, c)" |
|
4750 "nonstop (code tp) (bl2wc (<lm>)) stp' = 0" |
|
4751 thus "Suc stp \<le> stp'" |
|
4752 proof(case_tac "Suc stp \<le> stp'", simp, simp) |
|
4753 assume "\<not> Suc stp \<le> stp'" |
|
4754 hence "stp' \<le> stp" by simp |
|
4755 hence "\<not> isS0 (steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp')" |
|
4756 using g |
|
4757 apply(case_tac "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp'",auto, |
|
4758 simp add: isS0_def) |
|
4759 apply(subgoal_tac "\<exists> n. stp = stp' + n", |
|
4760 auto simp: steps_add steps_0) |
|
4761 apply(rule_tac x = "stp - stp'" in exI, simp) |
|
4762 done |
|
4763 hence "nonstop (code tp) (bl2wc (<lm>)) stp' = 1" |
|
4764 proof(case_tac "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp'", |
|
4765 simp add: isS0_def nonstop.simps) |
|
4766 fix a b c |
|
4767 assume k: |
|
4768 "0 < a" "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp' = (a, b, c)" |
|
4769 thus " NSTD (conf (code tp) (bl2wc (<lm>)) stp')" |
|
4770 using rec_t_eq_steps[of tp l lm stp'] h |
|
4771 proof(simp add: conf_lemma) |
|
4772 assume "trpl_code (a, b, c) = conf (code tp) (bl2wc (<lm>)) stp'" |
|
4773 moreover have "NSTD (trpl_code (a, b, c))" |
|
4774 using k |
|
4775 apply(auto simp: trpl_code.simps NSTD.simps) |
|
4776 done |
|
4777 ultimately show "NSTD (conf (code tp) (bl2wc (<lm>)) stp')" by simp |
|
4778 qed |
|
4779 qed |
|
4780 thus "False" using g by simp |
|
4781 qed |
|
4782 qed |
|
4783 qed |
|
4784 qed |
|
4785 |
|
4786 (* |
|
4787 lemma halt_steps_ex: |
|
4788 "\<lbrakk>steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>); |
|
4789 lm \<noteq> []; turing_basic.t_correct tp; 0<rs\<rbrakk> \<Longrightarrow> |
|
4790 \<exists> t. rec_calc_rel (rec_halt (length lm)) (code tp # lm) t" |
|
4791 apply(drule_tac halt_least_step, auto) |
|
4792 apply(rule_tac x = stp in exI) |
|
4793 apply(simp add: halt_lemma nonstop_lemma) |
|
4794 apply(auto) |
|
4795 done*) |
|
4796 thm loR.simps |
|
4797 |
|
4798 lemma conf_trpl_ex: "\<exists> p q r. conf m (bl2wc (<lm>)) stp = trpl p q r" |
|
4799 apply(induct stp, auto simp: conf.simps inpt.simps trpl.simps |
|
4800 newconf.simps) |
|
4801 apply(rule_tac x = 0 in exI, rule_tac x = 1 in exI, |
|
4802 rule_tac x = "bl2wc (<lm>)" in exI) |
|
4803 apply(simp) |
|
4804 done |
|
4805 |
|
4806 lemma nonstop_rgt_ex: |
|
4807 "nonstop m (bl2wc (<lm>)) stpa = 0 \<Longrightarrow> \<exists> r. conf m (bl2wc (<lm>)) stpa = trpl 0 0 r" |
|
4808 apply(auto simp: nonstop.simps NSTD.simps split: if_splits) |
|
4809 using conf_trpl_ex[of m lm stpa] |
|
4810 apply(auto) |
|
4811 done |
|
4812 |
|
4813 lemma [elim]: "x > Suc 0 \<Longrightarrow> Max {u. x ^ u dvd x ^ r} = r" |
|
4814 proof(rule_tac Max_eqI) |
|
4815 assume "x > Suc 0" |
|
4816 thus "finite {u. x ^ u dvd x ^ r}" |
|
4817 apply(rule_tac finite_power_dvd, auto) |
|
4818 done |
|
4819 next |
|
4820 fix y |
|
4821 assume "Suc 0 < x" "y \<in> {u. x ^ u dvd x ^ r}" |
|
4822 thus "y \<le> r" |
|
4823 apply(case_tac "y\<le> r", simp) |
|
4824 apply(subgoal_tac "\<exists> d. y = r + d") |
|
4825 apply(auto simp: power_add) |
|
4826 apply(rule_tac x = "y - r" in exI, simp) |
|
4827 done |
|
4828 next |
|
4829 show "r \<in> {u. x ^ u dvd x ^ r}" by simp |
|
4830 qed |
|
4831 |
|
4832 lemma lo_power: "x > Suc 0 \<Longrightarrow> lo (x ^ r) x = r" |
|
4833 apply(auto simp: lo.simps loR.simps mod_dvd_simp) |
|
4834 apply(case_tac "x^r", simp_all) |
|
4835 done |
|
4836 |
|
4837 lemma lo_rgt: "lo (trpl 0 0 r) (Pi 2) = r" |
|
4838 apply(simp add: trpl.simps lo_power) |
|
4839 done |
|
4840 |
|
4841 lemma conf_keep: |
|
4842 "conf m lm stp = trpl 0 0 r \<Longrightarrow> |
|
4843 conf m lm (stp + n) = trpl 0 0 r" |
|
4844 apply(induct n) |
|
4845 apply(auto simp: conf.simps newconf.simps newleft.simps |
|
4846 newrght.simps rght.simps lo_rgt) |
|
4847 done |
|
4848 |
|
4849 lemma halt_state_keep_steps_add: |
|
4850 "\<lbrakk>nonstop m (bl2wc (<lm>)) stpa = 0\<rbrakk> \<Longrightarrow> |
|
4851 conf m (bl2wc (<lm>)) stpa = conf m (bl2wc (<lm>)) (stpa + n)" |
|
4852 apply(drule_tac nonstop_rgt_ex, auto simp: conf_keep) |
|
4853 done |
|
4854 |
|
4855 lemma halt_state_keep: |
|
4856 "\<lbrakk>nonstop m (bl2wc (<lm>)) stpa = 0; nonstop m (bl2wc (<lm>)) stpb = 0\<rbrakk> \<Longrightarrow> |
|
4857 conf m (bl2wc (<lm>)) stpa = conf m (bl2wc (<lm>)) stpb" |
|
4858 apply(case_tac "stpa > stpb") |
|
4859 using halt_state_keep_steps_add[of m lm stpb "stpa - stpb"] |
|
4860 apply simp |
|
4861 using halt_state_keep_steps_add[of m lm stpa "stpb - stpa"] |
|
4862 apply(simp) |
|
4863 done |
|
4864 |
|
4865 thm halt_lemma |
|
4866 |
|
4867 text {* |
|
4868 The correntess of @{text "rec_F"} which relates the interpreter function @{text "rec_F"} with the |
|
4869 execution of of TMs. |
|
4870 *} |
|
4871 lemma F_t_halt_eq: |
|
4872 "\<lbrakk>steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup>@Bk\<^bsup>n\<^esup>); |
|
4873 turing_basic.t_correct tp; |
|
4874 0<rs\<rbrakk> |
|
4875 \<Longrightarrow> rec_calc_rel rec_F [code tp, (bl2wc (<lm>))] (rs - Suc 0)" |
|
4876 apply(frule_tac halt_least_step, auto) |
|
4877 apply(frule_tac nonstop_t_eq, auto simp: nonstop_lemma) |
|
4878 using rec_t_eq_steps[of tp l lm stp] |
|
4879 apply(simp add: conf_lemma) |
|
4880 proof - |
|
4881 fix stpa |
|
4882 assume h: |
|
4883 "nonstop (code tp) (bl2wc (<lm>)) stpa = 0" |
|
4884 "\<forall>stp'. nonstop (code tp) (bl2wc (<lm>)) stp' = 0 \<longrightarrow> stpa \<le> stp'" |
|
4885 "nonstop (code tp) (bl2wc (<lm>)) stp = 0" |
|
4886 "trpl_code (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>) = conf (code tp) (bl2wc (<lm>)) stp" |
|
4887 "steps (Suc 0, Bk\<^bsup>l\<^esup>, <lm>) tp stp = (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)" |
|
4888 hence g1: "conf (code tp) (bl2wc (<lm>)) stpa = trpl_code (0, Bk\<^bsup>m\<^esup>, Oc\<^bsup>rs\<^esup> @ Bk\<^bsup>n\<^esup>)" |
|
4889 using halt_state_keep[of "code tp" lm stpa stp] |
|
4890 by(simp) |
|
4891 moreover have g2: |
|
4892 "rec_calc_rel rec_halt [code tp, (bl2wc (<lm>))] stpa" |
|
4893 using h |
|
4894 apply(simp add: halt_lemma nonstop_lemma, auto) |
|
4895 done |
|
4896 show |
|
4897 "rec_calc_rel rec_F [code tp, (bl2wc (<lm>))] (rs - Suc 0)" |
|
4898 proof - |
|
4899 have |
|
4900 "rec_calc_rel rec_F [code tp, (bl2wc (<lm>))] |
|
4901 (valu (rght (conf (code tp) (bl2wc (<lm>)) stpa)))" |
|
4902 apply(rule F_lemma) using g2 h by auto |
|
4903 moreover have |
|
4904 "valu (rght (conf (code tp) (bl2wc (<lm>)) stpa)) = rs - Suc 0" |
|
4905 using g1 |
|
4906 apply(simp add: valu.simps trpl_code.simps |
|
4907 bl2wc.simps bl2nat_append lg_power) |
|
4908 done |
|
4909 ultimately show "?thesis" by simp |
|
4910 qed |
|
4911 qed |
|
4912 |
|
4913 |
|
4914 end |