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