2 imports Main Fact "~~/src/HOL/Number_Theory/Primes" |
2 imports Main Fact "~~/src/HOL/Number_Theory/Primes" |
3 begin |
3 begin |
4 |
4 |
5 lemma if_zero_one [simp]: |
5 lemma if_zero_one [simp]: |
6 "(if P then 1 else 0) = (0::nat) \<longleftrightarrow> \<not> P" |
6 "(if P then 1 else 0) = (0::nat) \<longleftrightarrow> \<not> P" |
7 "(if P then 0 else 1) = (0::nat) \<longleftrightarrow> P" |
|
8 "(0::nat) < (if P then 1 else 0) = P" |
7 "(0::nat) < (if P then 1 else 0) = P" |
|
8 "(if P then 0 else 1) = (if \<not>P then 1 else (0::nat))" |
9 by (simp_all) |
9 by (simp_all) |
10 |
10 |
11 lemma nth: |
11 lemma nth: |
12 "(x # xs) ! 0 = x" |
12 "(x # xs) ! 0 = x" |
13 "(x # y # xs) ! 1 = y" |
13 "(x # y # xs) ! 1 = y" |
14 "(x # y # z # xs) ! 2 = z" |
14 "(x # y # z # xs) ! 2 = z" |
15 "(x # y # z # u # xs) ! 3 = u" |
15 "(x # y # z # u # xs) ! 3 = u" |
16 by (simp_all) |
16 by (simp_all) |
17 |
17 |
18 lemma setprod_atMost_Suc[simp]: "(\<Prod>i \<le> Suc n. f i) = (\<Prod>i \<le> n. f i) * f(Suc n)" |
18 |
|
19 section {* Some auxiliary lemmas about @{text "\<Sum>"} and @{text "\<Prod>"} *} |
|
20 |
|
21 lemma setprod_atMost_Suc[simp]: |
|
22 "(\<Prod>i \<le> Suc n. f i) = (\<Prod>i \<le> n. f i) * f(Suc n)" |
19 by(simp add:atMost_Suc mult_ac) |
23 by(simp add:atMost_Suc mult_ac) |
20 |
24 |
21 lemma setprod_lessThan_Suc[simp]: "(\<Prod>i < Suc n. f i) = (\<Prod>i < n. f i) * f n" |
25 lemma setprod_lessThan_Suc[simp]: |
|
26 "(\<Prod>i < Suc n. f i) = (\<Prod>i < n. f i) * f n" |
22 by (simp add:lessThan_Suc mult_ac) |
27 by (simp add:lessThan_Suc mult_ac) |
23 |
28 |
24 lemma setsum_add_nat_ivl2: "n \<le> p \<Longrightarrow> |
29 lemma setsum_add_nat_ivl2: "n \<le> p \<Longrightarrow> |
25 setsum f {..<n} + setsum f {n..p} = setsum f {..p::nat}" |
30 setsum f {..<n} + setsum f {n..p} = setsum f {..p::nat}" |
26 apply(subst setsum_Un_disjoint[symmetric]) |
31 apply(subst setsum_Un_disjoint[symmetric]) |
27 apply(auto simp add: ivl_disj_un_one) |
32 apply(auto simp add: ivl_disj_un_one) |
28 done |
33 done |
29 |
34 |
30 |
|
31 lemma setsum_eq_zero [simp]: |
35 lemma setsum_eq_zero [simp]: |
32 fixes n::nat |
36 fixes f::"nat \<Rightarrow> nat" |
33 shows "(\<Sum>i < n. f i) = (0::nat) \<longleftrightarrow> (\<forall>i < n. f i = 0)" |
37 shows "(\<Sum>i < n. f i) = 0 \<longleftrightarrow> (\<forall>i < n. f i = 0)" |
34 "(\<Sum>i \<le> n. f i) = (0::nat) \<longleftrightarrow> (\<forall>i \<le> n. f i = 0)" |
38 "(\<Sum>i \<le> n. f i) = 0 \<longleftrightarrow> (\<forall>i \<le> n. f i = 0)" |
35 by (auto) |
39 by (auto) |
36 |
40 |
37 lemma setprod_eq_zero [simp]: |
41 lemma setprod_eq_zero [simp]: |
38 fixes n::nat |
42 fixes f::"nat \<Rightarrow> nat" |
39 shows "(\<Prod>i < n. f i) = (0::nat) \<longleftrightarrow> (\<exists>i < n. f i = 0)" |
43 shows "(\<Prod>i < n. f i) = 0 \<longleftrightarrow> (\<exists>i < n. f i = 0)" |
40 "(\<Prod>i \<le> n. f i) = (0::nat) \<longleftrightarrow> (\<exists>i \<le> n. f i = 0)" |
44 "(\<Prod>i \<le> n. f i) = 0 \<longleftrightarrow> (\<exists>i \<le> n. f i = 0)" |
41 by (auto) |
45 by (auto) |
42 |
46 |
43 lemma setsum_one_less: |
47 lemma setsum_one_less: |
44 fixes n::nat |
48 fixes n::nat |
45 assumes "\<forall>i < n. f i \<le> 1" |
49 assumes "\<forall>i < n. f i \<le> 1" |
76 using h0 by (simp add: setsum_add_nat_ivl2) |
80 using h0 by (simp add: setsum_add_nat_ivl2) |
77 also have "... = (\<Sum>i \<in> {..<p}. f i)" using eq_zero by simp |
81 also have "... = (\<Sum>i \<in> {..<p}. f i)" using eq_zero by simp |
78 finally show "(\<Sum>i \<le> n. f i) = p" using eq_p by simp |
82 finally show "(\<Sum>i \<le> n. f i) = p" using eq_p by simp |
79 qed |
83 qed |
80 |
84 |
|
85 lemma nat_mult_le_one: |
|
86 fixes m n::nat |
|
87 assumes "m \<le> 1" "n \<le> 1" |
|
88 shows "m * n \<le> 1" |
|
89 using assms by (induct n) (auto) |
|
90 |
81 lemma setprod_one_le: |
91 lemma setprod_one_le: |
82 fixes n::nat |
92 fixes f::"nat \<Rightarrow> nat" |
83 assumes "\<forall>i \<le> n. f i \<le> (1::nat)" |
93 assumes "\<forall>i \<le> n. f i \<le> 1" |
84 shows "(\<Prod>i \<le> n. f i) \<le> 1" |
94 shows "(\<Prod>i \<le> n. f i) \<le> 1" |
85 using assms |
95 using assms by (induct n) (auto intro: nat_mult_le_one) |
86 apply(induct n) |
|
87 apply(auto) |
|
88 by (metis One_nat_def eq_iff le_0_eq le_SucE mult_0 nat_mult_1) |
|
89 |
96 |
90 lemma setprod_greater_zero: |
97 lemma setprod_greater_zero: |
91 fixes n::nat |
98 fixes f::"nat \<Rightarrow> nat" |
92 assumes "\<forall>i \<le> n. f i \<ge> (0::nat)" |
99 assumes "\<forall>i \<le> n. f i \<ge> 0" |
93 shows "(\<Prod>i \<le> n. f i) \<ge> 0" |
100 shows "(\<Prod>i \<le> n. f i) \<ge> 0" |
94 using assms |
101 using assms by (induct n) (auto) |
95 by (induct n) (auto) |
|
96 |
102 |
97 lemma setprod_eq_one: |
103 lemma setprod_eq_one: |
98 fixes n::nat |
104 fixes f::"nat \<Rightarrow> nat" |
99 assumes "\<forall>i \<le> n. f i = Suc 0" |
105 assumes "\<forall>i \<le> n. f i = Suc 0" |
100 shows "(\<Prod>i \<le> n. f i) = Suc 0" |
106 shows "(\<Prod>i \<le> n. f i) = Suc 0" |
101 using assms |
107 using assms by (induct n) (auto) |
102 by (induct n) (auto) |
|
103 |
108 |
104 lemma setsum_cut_off_less: |
109 lemma setsum_cut_off_less: |
105 fixes n::nat |
110 fixes f::"nat \<Rightarrow> nat" |
106 assumes h1: "m \<le> n" |
111 assumes h1: "m \<le> n" |
107 and h2: "\<forall>i \<in> {m..<n}. f i = 0" |
112 and h2: "\<forall>i \<in> {m..<n}. f i = 0" |
108 shows "(\<Sum>i < n. f i) = (\<Sum>i < m. f i)" |
113 shows "(\<Sum>i < n. f i) = (\<Sum>i < m. f i)" |
109 proof - |
114 proof - |
110 have eq_zero: "(\<Sum>i \<in> {m..<n}. f i) = 0" |
115 have eq_zero: "(\<Sum>i \<in> {m..<n}. f i) = 0" |
158 abbreviation |
166 abbreviation |
159 "PR f g \<equiv> Pr (arity f) f g" |
167 "PR f g \<equiv> Pr (arity f) f g" |
160 |
168 |
161 fun rec_eval :: "recf \<Rightarrow> nat list \<Rightarrow> nat" |
169 fun rec_eval :: "recf \<Rightarrow> nat list \<Rightarrow> nat" |
162 where |
170 where |
163 "rec_eval z xs = 0" |
171 "rec_eval Z xs = 0" |
164 | "rec_eval s xs = Suc (xs ! 0)" |
172 | "rec_eval S xs = Suc (xs ! 0)" |
165 | "rec_eval (id m n) xs = xs ! n" |
173 | "rec_eval (Id m n) xs = xs ! n" |
166 | "rec_eval (Cn n f gs) xs = rec_eval f (map (\<lambda>x. rec_eval x xs) gs)" |
174 | "rec_eval (Cn n f gs) xs = rec_eval f (map (\<lambda>x. rec_eval x xs) gs)" |
167 | "rec_eval (Pr n f g) (0 # xs) = rec_eval f xs" |
175 | "rec_eval (Pr n f g) (0 # xs) = rec_eval f xs" |
168 | "rec_eval (Pr n f g) (Suc x # xs) = |
176 | "rec_eval (Pr n f g) (Suc x # xs) = |
169 rec_eval g (x # (rec_eval (Pr n f g) (x # xs)) # xs)" |
177 rec_eval g (x # (rec_eval (Pr n f g) (x # xs)) # xs)" |
170 | "rec_eval (Mn n f) xs = (LEAST x. rec_eval f (x # xs) = 0)" |
178 | "rec_eval (Mn n f) xs = (LEAST x. rec_eval f (x # xs) = 0)" |
171 |
179 |
172 inductive |
180 inductive |
173 terminates :: "recf \<Rightarrow> nat list \<Rightarrow> bool" |
181 terminates :: "recf \<Rightarrow> nat list \<Rightarrow> bool" |
174 where |
182 where |
175 termi_z: "terminates z [n]" |
183 termi_z: "terminates Z [n]" |
176 | termi_s: "terminates s [n]" |
184 | termi_s: "terminates S [n]" |
177 | termi_id: "\<lbrakk>n < m; length xs = m\<rbrakk> \<Longrightarrow> terminates (id m n) xs" |
185 | termi_id: "\<lbrakk>n < m; length xs = m\<rbrakk> \<Longrightarrow> terminates (Id m n) xs" |
178 | termi_cn: "\<lbrakk>terminates f (map (\<lambda>g. rec_eval g xs) gs); |
186 | termi_cn: "\<lbrakk>terminates f (map (\<lambda>g. rec_eval g xs) gs); |
179 \<forall>g \<in> set gs. terminates g xs; length xs = n\<rbrakk> \<Longrightarrow> terminates (Cn n f gs) xs" |
187 \<forall>g \<in> set gs. terminates g xs; length xs = n\<rbrakk> \<Longrightarrow> terminates (Cn n f gs) xs" |
180 | termi_pr: "\<lbrakk>\<forall> y < x. terminates g (y # (rec_eval (Pr n f g) (y # xs) # xs)); |
188 | termi_pr: "\<lbrakk>\<forall> y < x. terminates g (y # (rec_eval (Pr n f g) (y # xs) # xs)); |
181 terminates f xs; |
189 terminates f xs; |
182 length xs = n\<rbrakk> |
190 length xs = n\<rbrakk> |
192 @{text "constn n"} is the recursive function which computes |
200 @{text "constn n"} is the recursive function which computes |
193 natural number @{text "n"}. |
201 natural number @{text "n"}. |
194 *} |
202 *} |
195 fun constn :: "nat \<Rightarrow> recf" |
203 fun constn :: "nat \<Rightarrow> recf" |
196 where |
204 where |
197 "constn 0 = z" | |
205 "constn 0 = Z" | |
198 "constn (Suc n) = CN s [constn n]" |
206 "constn (Suc n) = CN S [constn n]" |
199 |
207 |
200 definition |
208 definition |
201 "rec_swap f = CN f [id 2 1, id 2 0]" |
209 "rec_swap f = CN f [Id 2 1, Id 2 0]" |
202 |
210 |
203 definition |
211 definition |
204 "rec_add = PR (id 1 0) (CN s [id 3 1])" |
212 "rec_add = PR (Id 1 0) (CN S [Id 3 1])" |
205 |
213 |
206 definition |
214 definition |
207 "rec_mult = PR z (CN rec_add [id 3 1, id 3 2])" |
215 "rec_mult = PR Z (CN rec_add [Id 3 1, Id 3 2])" |
208 |
216 |
209 definition |
217 definition |
210 "rec_power_swap = PR (constn 1) (CN rec_mult [id 3 1, id 3 2])" |
218 "rec_power_swap = PR (constn 1) (CN rec_mult [Id 3 1, Id 3 2])" |
211 |
219 |
212 definition |
220 definition |
213 "rec_power = rec_swap rec_power_swap" |
221 "rec_power = rec_swap rec_power_swap" |
214 |
222 |
215 definition |
223 definition |
216 "rec_fact = PR (constn 1) (CN rec_mult [CN s [id 3 0], id 3 1])" |
224 "rec_fact = PR (constn 1) (CN rec_mult [CN S [Id 3 0], Id 3 1])" |
217 |
225 |
218 definition |
226 definition |
219 "rec_pred = CN (PR z (id 3 0)) [id 1 0, id 1 0]" |
227 "rec_pred = CN (PR Z (Id 3 0)) [Id 1 0, Id 1 0]" |
220 |
228 |
221 definition |
229 definition |
222 "rec_minus_swap = (PR (id 1 0) (CN rec_pred [id 3 1]))" |
230 "rec_minus_swap = (PR (Id 1 0) (CN rec_pred [Id 3 1]))" |
223 |
231 |
224 definition |
232 definition |
225 "rec_minus = rec_swap rec_minus_swap" |
233 "rec_minus = rec_swap rec_minus_swap" |
226 |
234 |
227 text {* Sign function returning 1 when the input argument is greater than @{text "0"}. *} |
235 text {* Sign function returning 1 when the input argument is greater than @{text "0"}. *} |
228 definition |
236 |
229 "rec_sign = CN rec_minus [constn 1, CN rec_minus [constn 1, id 1 0]]" |
237 definition |
230 |
238 "rec_sign = CN rec_minus [constn 1, CN rec_minus [constn 1, Id 1 0]]" |
231 definition |
239 |
232 "rec_not = CN rec_minus [constn 1, id 1 0]" |
240 definition |
|
241 "rec_not = CN rec_minus [constn 1, Id 1 0]" |
233 |
242 |
234 text {* |
243 text {* |
235 @{text "rec_eq"} compares two arguments: returns @{text "1"} |
244 @{text "rec_eq"} compares two arguments: returns @{text "1"} |
236 if they are equal; @{text "0"} otherwise. *} |
245 if they are equal; @{text "0"} otherwise. *} |
237 definition |
246 definition |
238 "rec_eq = CN rec_minus |
247 "rec_eq = CN rec_minus |
239 [CN (constn 1) [id 2 0], |
248 [CN (constn 1) [Id 2 0], |
240 CN rec_add [rec_minus, rec_swap rec_minus]]" |
249 CN rec_add [rec_minus, rec_swap rec_minus]]" |
241 |
250 |
242 definition |
251 definition |
243 "rec_noteq = CN rec_not [rec_eq]" |
252 "rec_noteq = CN rec_not [rec_eq]" |
244 |
253 |
422 |
442 |
423 lemma dvd_lemma [simp]: |
443 lemma dvd_lemma [simp]: |
424 "rec_eval rec_dvd [x, y] = (if x dvd y then 1 else 0)" |
444 "rec_eval rec_dvd [x, y] = (if x dvd y then 1 else 0)" |
425 by (simp add: rec_dvd_def) |
445 by (simp add: rec_dvd_def) |
426 |
446 |
427 definition |
447 |
428 "rec_prime = |
448 section {* Prime Numbers *} |
429 (let conj1 = CN rec_less [constn 1, id 1 0] in |
|
430 let disj = CN rec_disj [CN rec_eq [id 2 0, constn 1], rec_eq] in |
|
431 let imp = CN rec_imp [rec_dvd, disj] in |
|
432 let conj2 = CN (rec_all1 imp) [id 1 0, id 1 0] in |
|
433 CN rec_conj [conj1, conj2])" |
|
434 |
449 |
435 lemma prime_alt_def: |
450 lemma prime_alt_def: |
436 fixes p::nat |
451 fixes p::nat |
437 shows "prime p = (1 < p \<and> (\<forall>m \<le> p. m dvd p \<longrightarrow> m = 1 \<or> m = p))" |
452 shows "prime p = (1 < p \<and> (\<forall>m \<le> p. m dvd p \<longrightarrow> m = 1 \<or> m = p))" |
438 apply(auto simp add: prime_nat_def dvd_def) |
453 apply(auto simp add: prime_nat_def dvd_def) |
439 by (metis One_nat_def le_neq_implies_less less_SucI less_Suc_eq_0_disj less_Suc_eq_le mult_is_0 n_less_n_mult_m not_less_eq_eq) |
454 apply(drule_tac x="k" in spec) |
|
455 apply(auto) |
|
456 done |
|
457 |
|
458 definition |
|
459 "rec_prime = |
|
460 (let conj1 = CN rec_less [constn 1, Id 1 0] in |
|
461 let disj = CN rec_disj [CN rec_eq [Id 2 0, constn 1], rec_eq] in |
|
462 let imp = CN rec_imp [rec_dvd, disj] in |
|
463 let conj2 = CN (rec_all1 imp) [Id 1 0, Id 1 0] in |
|
464 CN rec_conj [conj1, conj2])" |
440 |
465 |
441 lemma prime_lemma [simp]: |
466 lemma prime_lemma [simp]: |
442 "rec_eval rec_prime [x] = (if prime x then 1 else 0)" |
467 "rec_eval rec_prime [x] = (if prime x then 1 else 0)" |
443 by (simp add: rec_prime_def Let_def prime_alt_def) |
468 by (auto simp add: rec_prime_def Let_def prime_alt_def) |
|
469 |
|
470 section {* Bounded Min and Maximisation *} |
|
471 |
|
472 fun BMax_rec where |
|
473 "BMax_rec R 0 = 0" |
|
474 | "BMax_rec R (Suc n) = (if R (Suc n) then (Suc n) else BMax_rec R n)" |
|
475 |
|
476 definition BMax_set :: "(nat \<Rightarrow> bool) \<Rightarrow> nat \<Rightarrow> nat" |
|
477 where "BMax_set R x = Max ({z | z. z \<le> x \<and> R z} \<union> {0})" |
|
478 |
|
479 definition (in ord) |
|
480 Great :: "('a \<Rightarrow> bool) \<Rightarrow> 'a" (binder "GREAT " 10) where |
|
481 "Great P = (THE x. P x \<and> (\<forall>y. P y \<longrightarrow> y \<le> x))" |
|
482 |
|
483 lemma Great_equality: |
|
484 fixes x::nat |
|
485 assumes "P x" "\<And>y. P y \<Longrightarrow> y \<le> x" |
|
486 shows "Great P = x" |
|
487 unfolding Great_def |
|
488 using assms |
|
489 by(rule_tac the_equality) (auto intro: le_antisym) |
|
490 |
|
491 lemma BMax_rec_eq1: |
|
492 "BMax_rec R x = (GREAT z. (R z \<and> z \<le> x) \<or> z = 0)" |
|
493 apply(induct x) |
|
494 apply(auto intro: Great_equality Great_equality[symmetric]) |
|
495 apply(simp add: le_Suc_eq) |
|
496 by metis |
|
497 |
|
498 lemma BMax_rec_eq2: |
|
499 "BMax_rec R x = Max ({z | z. z \<le> x \<and> R z} \<union> {0})" |
|
500 apply(induct x) |
|
501 apply(auto intro: Max_eqI Max_eqI[symmetric]) |
|
502 apply(simp add: le_Suc_eq) |
|
503 by metis |
|
504 |
|
505 definition |
|
506 "rec_max1 f = PR (constn 0) |
|
507 (CN rec_ifz [CN f [CN S [Id 3 0], Id 3 2], CN S [Id 4 0], Id 4 1])" |
|
508 |
|
509 lemma max1_lemma [simp]: |
|
510 "rec_eval (rec_max1 f) [x, y] = BMax_rec (\<lambda>u. rec_eval f [u, y] = 0) x" |
|
511 by (induct x) (simp_all add: rec_max1_def) |
|
512 |
|
513 definition |
|
514 "rec_max2 f = PR (constn 0) |
|
515 (CN rec_ifz [CN f [CN S [Id 4 0], Id 4 2, Id 4 3], CN S [Id 4 0], Id 4 1])" |
|
516 |
|
517 lemma max2_lemma [simp]: |
|
518 "rec_eval (rec_max2 f) [x, y1, y2] = BMax_rec (\<lambda>u. rec_eval f [u, y1, y2] = 0) x" |
|
519 by (induct x) (simp_all add: rec_max2_def) |
|
520 |
|
521 definition |
|
522 "rec_lg = |
|
523 (let calc = CN rec_not [CN rec_le [CN rec_power [Id 3 2, Id 3 0], Id 3 1]] in |
|
524 let max = CN (rec_max2 calc) [Id 2 0, Id 2 0, Id 2 1] in |
|
525 let cond = CN rec_conj [CN rec_less [constn 1, Id 2 0], CN rec_less [constn 1, Id 2 1]] |
|
526 in CN rec_ifz [cond, Z, max])" |
|
527 |
|
528 definition |
|
529 "Lg x y = (if 1 < x \<and> 1 < y then BMax_rec (\<lambda>u. y ^ u \<le> x) x else 0)" |
|
530 |
|
531 lemma lg_lemma: |
|
532 "rec_eval rec_lg [x, y] = Lg x y" |
|
533 by (simp add: rec_lg_def Lg_def Let_def) |
|
534 |
|
535 |
|
536 |
|
537 |
|
538 |
|
539 fun mtest where |
|
540 "mtest R 0 = if R 0 then 0 else 1" |
|
541 | "mtest R (Suc n) = (if R n then mtest R n else (Suc n))" |
|
542 |
|
543 |
|
544 lemma |
|
545 "rec_eval (rec_maxr2 f) [x, y1, y2] = XXX" |
|
546 apply(simp only: rec_maxr2_def) |
|
547 apply(case_tac x) |
|
548 apply(clarify) |
|
549 apply(subst rec_eval.simps) |
|
550 apply(simp only: constn_lemma) |
|
551 defer |
|
552 apply(clarify) |
|
553 apply(subst rec_eval.simps) |
|
554 apply(simp only: rec_maxr2_def[symmetric]) |
|
555 apply(subst rec_eval.simps) |
|
556 apply(simp only: map.simps nth) |
|
557 apply(subst rec_eval.simps) |
|
558 apply(simp only: map.simps nth) |
|
559 apply(subst rec_eval.simps) |
|
560 apply(simp only: map.simps nth) |
|
561 apply(subst rec_eval.simps) |
|
562 apply(simp only: map.simps nth) |
|
563 apply(subst rec_eval.simps) |
|
564 apply(simp only: map.simps nth) |
|
565 apply(subst rec_eval.simps) |
|
566 apply(simp only: map.simps nth) |
|
567 |
444 |
568 |
445 definition |
569 definition |
446 "rec_minr2 f = rec_sigma2 (rec_accum2 (CN rec_not [f]))" |
570 "rec_minr2 f = rec_sigma2 (rec_accum2 (CN rec_not [f]))" |
447 |
571 |
448 fun Minr2 :: "(nat list \<Rightarrow> bool) \<Rightarrow> nat list \<Rightarrow> nat" |
572 definition |
449 where "Minr2 R (x # ys) = Min ({z | z. z \<le> x \<and> R (z # ys)} \<union> {Suc x})" |
573 "rec_maxr2 f = rec_sigma2 (CN rec_sign [CN (rec_sigma2 f) [S]])" |
|
574 |
|
575 definition Minr :: "(nat \<Rightarrow> nat list \<Rightarrow> bool) \<Rightarrow> nat \<Rightarrow> nat list \<Rightarrow> nat" |
|
576 where "Minr R x ys = Min ({z | z. z \<le> x \<and> R z ys} \<union> {Suc x})" |
|
577 |
|
578 definition Maxr :: "(nat \<Rightarrow> nat list \<Rightarrow> bool) \<Rightarrow> nat \<Rightarrow> nat list \<Rightarrow> nat" |
|
579 where "Maxr R x ys = Max ({z | z. z \<le> x \<and> R z ys} \<union> {0})" |
|
580 |
|
581 lemma rec_minr2_le_Suc: |
|
582 "rec_eval (rec_minr2 f) [x, y1, y2] \<le> Suc x" |
|
583 apply(simp add: rec_minr2_def) |
|
584 apply(auto intro!: setsum_one_le setprod_one_le) |
|
585 done |
|
586 |
|
587 lemma rec_minr2_eq_Suc: |
|
588 assumes "\<forall>z \<le> x. rec_eval f [z, y1, y2] = 0" |
|
589 shows "rec_eval (rec_minr2 f) [x, y1, y2] = Suc x" |
|
590 using assms by (simp add: rec_minr2_def) |
|
591 |
|
592 lemma rec_minr2_le: |
|
593 assumes h1: "y \<le> x" |
|
594 and h2: "0 < rec_eval f [y, y1, y2]" |
|
595 shows "rec_eval (rec_minr2 f) [x, y1, y2] \<le> y" |
|
596 apply(simp add: rec_minr2_def) |
|
597 apply(subst setsum_cut_off_le[OF h1]) |
|
598 using h2 apply(auto) |
|
599 apply(auto intro!: setsum_one_less setprod_one_le) |
|
600 done |
|
601 |
|
602 (* ??? *) |
|
603 lemma setsum_eq_one_le2: |
|
604 fixes n::nat |
|
605 assumes "\<forall>i \<le> n. f i \<le> 1" |
|
606 shows "((\<Sum>i \<le> n. f i) \<ge> Suc n) \<Longrightarrow> (\<forall>i \<le> n. f i = 1)" |
|
607 using assms |
|
608 apply(induct n) |
|
609 apply(simp add: One_nat_def) |
|
610 apply(simp) |
|
611 apply(auto simp add: One_nat_def) |
|
612 apply(drule_tac x="Suc n" in spec) |
|
613 apply(auto) |
|
614 by (metis le_Suc_eq) |
|
615 |
|
616 |
|
617 lemma rec_min2_not: |
|
618 assumes "rec_eval (rec_minr2 f) [x, y1, y2] = Suc x" |
|
619 shows "\<forall>z \<le> x. rec_eval f [z, y1, y2] = 0" |
|
620 using assms |
|
621 apply(simp add: rec_minr2_def) |
|
622 apply(subgoal_tac "\<forall>i \<le> x. (\<Prod>z\<le>i. if rec_eval f [z, y1, y2] = 0 then 1 else 0) = (1::nat)") |
|
623 apply(simp) |
|
624 apply (metis atMost_iff le_refl zero_neq_one) |
|
625 apply(rule setsum_eq_one_le2) |
|
626 apply(auto) |
|
627 apply(rule setprod_one_le) |
|
628 apply(auto) |
|
629 done |
|
630 |
|
631 lemma disjCI2: |
|
632 assumes "~P ==> Q" shows "P|Q" |
|
633 apply (rule classical) |
|
634 apply (iprover intro: assms disjI1 disjI2 notI elim: notE) |
|
635 done |
450 |
636 |
451 lemma minr_lemma [simp]: |
637 lemma minr_lemma [simp]: |
452 shows "rec_eval (rec_minr2 f) [x, y1, y2] = Minr2 (\<lambda>xs. (0 < rec_eval f xs)) [x, y1, y2]" |
638 shows "rec_eval (rec_minr2 f) [x, y1, y2] = (LEAST z. (z \<le> x \<and> 0 < rec_eval f [z, y1, y2]) \<or> z = Suc x)" |
453 apply(simp only: rec_minr2_def) |
639 apply(induct x) |
454 apply(simp) |
640 apply(rule Least_equality[symmetric]) |
|
641 apply(simp add: rec_minr2_def) |
|
642 apply(erule disjE) |
|
643 apply(rule rec_minr2_le) |
|
644 apply(auto)[2] |
|
645 apply(simp) |
|
646 apply(rule rec_minr2_le_Suc) |
|
647 apply(simp) |
|
648 |
|
649 apply(rule rec_minr2_le) |
|
650 |
|
651 |
|
652 apply(rule rec_minr2_le_Suc) |
|
653 apply(rule disjCI) |
|
654 apply(simp add: rec_minr2_def) |
|
655 |
|
656 apply(ru le setsum_one_less) |
|
657 apply(clarify) |
|
658 apply(rule setprod_one_le) |
|
659 apply(auto)[1] |
|
660 apply(simp) |
|
661 apply(rule setsum_one_le) |
|
662 apply(clarify) |
|
663 apply(rule setprod_one_le) |
|
664 apply(auto)[1] |
|
665 thm disj_CE |
|
666 apply(auto) |
|
667 |
|
668 lemma minr_lemma: |
|
669 shows "rec_eval (rec_minr2 f) [x, y1, y2] = Minr (\<lambda>x xs. (0 < rec_eval f (x #xs))) x [y1, y2]" |
|
670 apply(simp only: Minr_def) |
455 apply(rule sym) |
671 apply(rule sym) |
456 apply(rule Min_eqI) |
672 apply(rule Min_eqI) |
457 apply(auto)[1] |
673 apply(auto)[1] |
458 apply(simp) |
674 apply(simp) |
459 apply(erule disjE) |
675 apply(erule disjE) |
460 apply(simp) |
676 apply(simp) |
|
677 apply(rule rec_minr2_le_Suc) |
|
678 apply(rule rec_minr2_le) |
|
679 apply(auto)[2] |
|
680 apply(simp) |
|
681 apply(induct x) |
|
682 apply(simp add: rec_minr2_def) |
|
683 apply( |
|
684 apply(rule disjCI) |
|
685 apply(rule rec_minr2_eq_Suc) |
|
686 apply(simp) |
|
687 apply(auto) |
|
688 |
461 apply(rule setsum_one_le) |
689 apply(rule setsum_one_le) |
462 apply(auto)[1] |
690 apply(auto)[1] |
463 apply(rule setprod_one_le) |
691 apply(rule setprod_one_le) |
464 apply(auto)[1] |
692 apply(auto)[1] |
465 apply(subst setsum_cut_off_le) |
693 apply(subst setsum_cut_off_le) |
513 apply (metis neq0_conv not_less_Least) |
741 apply (metis neq0_conv not_less_Least) |
514 apply(auto)[1] |
742 apply(auto)[1] |
515 apply (metis (mono_tags) LeastI_ex) |
743 apply (metis (mono_tags) LeastI_ex) |
516 by (metis LeastI_ex) |
744 by (metis LeastI_ex) |
517 |
745 |
|
746 lemma minr_lemma: |
|
747 shows "rec_eval (rec_minr2 f) [x, y1, y2] = Minr (\<lambda>x xs. (0 < rec_eval f (x #xs))) x [y1, y2]" |
|
748 apply(simp only: Minr_def rec_minr2_def) |
|
749 apply(simp) |
|
750 apply(rule sym) |
|
751 apply(rule Min_eqI) |
|
752 apply(auto)[1] |
|
753 apply(simp) |
|
754 apply(erule disjE) |
|
755 apply(simp) |
|
756 apply(rule setsum_one_le) |
|
757 apply(auto)[1] |
|
758 apply(rule setprod_one_le) |
|
759 apply(auto)[1] |
|
760 apply(subst setsum_cut_off_le) |
|
761 apply(auto)[2] |
|
762 apply(rule setsum_one_less) |
|
763 apply(auto)[1] |
|
764 apply(rule setprod_one_le) |
|
765 apply(auto)[1] |
|
766 apply(simp) |
|
767 thm setsum_eq_one_le |
|
768 apply(subgoal_tac "(\<forall>z\<le>x. (\<Prod>z\<le>z. if rec_eval f [z, y1, y2] = (0::nat) then 1 else 0) > (0::nat)) \<or> |
|
769 (\<not> (\<forall>z\<le>x. (\<Prod>z\<le>z. if rec_eval f [z, y1, y2] = (0::nat) then 1 else 0) > (0::nat)))") |
|
770 prefer 2 |
|
771 apply(auto)[1] |
|
772 apply(erule disjE) |
|
773 apply(rule disjI1) |
|
774 apply(rule setsum_eq_one_le) |
|
775 apply(simp) |
|
776 apply(rule disjI2) |
|
777 apply(simp) |
|
778 apply(clarify) |
|
779 apply(subgoal_tac "\<exists>l. l = (LEAST z. 0 < rec_eval f [z, y1, y2])") |
|
780 defer |
|
781 apply metis |
|
782 apply(erule exE) |
|
783 apply(subgoal_tac "l \<le> x") |
|
784 defer |
|
785 apply (metis not_leE not_less_Least order_trans) |
|
786 apply(subst setsum_least_eq) |
|
787 apply(rotate_tac 4) |
|
788 apply(assumption) |
|
789 apply(auto)[1] |
|
790 apply(subgoal_tac "a < (LEAST z. 0 < rec_eval f [z, y1, y2])") |
|
791 prefer 2 |
|
792 apply(auto)[1] |
|
793 apply(rotate_tac 5) |
|
794 apply(drule not_less_Least) |
|
795 apply(auto)[1] |
|
796 apply(auto) |
|
797 apply(rule_tac x="(LEAST z. 0 < rec_eval f [z, y1, y2])" in exI) |
|
798 apply(simp) |
|
799 apply (metis LeastI_ex) |
|
800 apply(subst setsum_least_eq) |
|
801 apply(rotate_tac 3) |
|
802 apply(assumption) |
|
803 apply(simp) |
|
804 apply(auto)[1] |
|
805 apply(subgoal_tac "a < (LEAST z. 0 < rec_eval f [z, y1, y2])") |
|
806 prefer 2 |
|
807 apply(auto)[1] |
|
808 apply (metis neq0_conv not_less_Least) |
|
809 apply(auto)[1] |
|
810 apply (metis (mono_tags) LeastI_ex) |
|
811 by (metis LeastI_ex) |
|
812 |
|
813 lemma disjCI2: |
|
814 assumes "~P ==> Q" shows "P|Q" |
|
815 apply (rule classical) |
|
816 apply (iprover intro: assms disjI1 disjI2 notI elim: notE) |
|
817 done |
|
818 |
|
819 |
|
820 lemma minr_lemma [simp]: |
|
821 shows "rec_eval (rec_minr2 f) [x, y1, y2] = (LEAST z. (z \<le> x \<and> 0 < rec_eval f [z, y1, y2]) \<or> z = Suc x)" |
|
822 (*apply(simp add: rec_minr2_def)*) |
|
823 apply(rule Least_equality[symmetric]) |
|
824 prefer 2 |
|
825 apply(erule disjE) |
|
826 apply(rule rec_minr2_le) |
|
827 apply(auto)[2] |
|
828 apply(clarify) |
|
829 apply(rule rec_minr2_le_Suc) |
|
830 apply(rule disjCI) |
|
831 apply(simp add: rec_minr2_def) |
|
832 |
|
833 apply(ru le setsum_one_less) |
|
834 apply(clarify) |
|
835 apply(rule setprod_one_le) |
|
836 apply(auto)[1] |
|
837 apply(simp) |
|
838 apply(rule setsum_one_le) |
|
839 apply(clarify) |
|
840 apply(rule setprod_one_le) |
|
841 apply(auto)[1] |
|
842 thm disj_CE |
|
843 apply(auto) |
|
844 apply(auto) |
|
845 prefer 2 |
|
846 apply(rule le_tran |
|
847 |
|
848 apply(rule le_trans) |
|
849 apply(simp) |
|
850 defer |
|
851 apply(auto) |
|
852 apply(subst setsum_cut_off_le) |
|
853 |
|
854 |
|
855 lemma |
|
856 "Minr R x ys = (LEAST z. (R z ys \<or> z = Suc x))" |
|
857 apply(simp add: Minr_def) |
|
858 apply(rule Min_eqI) |
|
859 apply(auto)[1] |
|
860 apply(simp) |
|
861 apply(rule Least_le) |
|
862 apply(auto)[1] |
|
863 apply(rule LeastI2_wellorder) |
|
864 apply(auto) |
|
865 done |
|
866 |
|
867 definition (in ord) |
|
868 Great :: "('a \<Rightarrow> bool) \<Rightarrow> 'a" (binder "GREAT " 10) where |
|
869 "Great P = (THE x. P x \<and> (\<forall>y. P y \<longrightarrow> y \<le> x))" |
|
870 |
|
871 (* |
|
872 lemma Great_equality: |
|
873 assumes "P x" |
|
874 and "\<And>y. P y \<Longrightarrow> y \<le> x" |
|
875 shows "Great P = x" |
|
876 unfolding Great_def |
|
877 apply(rule the_equality) |
|
878 apply(blast intro: assms) |
|
879 *) |
|
880 |
|
881 |
|
882 |
|
883 lemma |
|
884 "Maxr R x ys = (GREAT z. (R z ys \<or> z = 0))" |
|
885 apply(simp add: Maxr_def) |
|
886 apply(rule Max_eqI) |
|
887 apply(auto)[1] |
|
888 apply(simp) |
|
889 thm Least_le Greatest_le |
|
890 oops |
|
891 |
|
892 lemma |
|
893 "Maxr R x ys = x - Minr (\<lambda>z. R (x - z)) x ys" |
|
894 apply(simp add: Maxr_def Minr_def) |
|
895 apply(rule Max_eqI) |
|
896 apply(auto)[1] |
|
897 apply(simp) |
|
898 apply(erule disjE) |
|
899 apply(simp) |
|
900 apply(auto)[1] |
|
901 defer |
|
902 apply(simp) |
|
903 apply(auto)[1] |
|
904 thm Min_insert |
|
905 defer |
|
906 oops |
|
907 |
|
908 |
|
909 |
518 definition quo :: "nat \<Rightarrow> nat \<Rightarrow> nat" |
910 definition quo :: "nat \<Rightarrow> nat \<Rightarrow> nat" |
519 where |
911 where |
520 "quo x y = (if y = 0 then 0 else x div y)" |
912 "quo x y = (if y = 0 then 0 else x div y)" |
521 |
913 |
522 |
914 |
523 definition |
915 definition |
524 "rec_quo = CN rec_mult [CN rec_sign [id 2 1], |
916 "rec_quo = CN rec_mult [CN rec_sign [Id 2 1], |
525 CN (rec_minr2 (CN rec_less [id 3 1, CN rec_mult [CN s [id 3 0], id 3 2]])) |
917 CN (rec_minr2 (CN rec_less [Id 3 1, CN rec_mult [CN S [Id 3 0], Id 3 2]])) |
526 [id 2 0, id 2 0, id 2 1]]" |
918 [Id 2 0, Id 2 0, Id 2 1]]" |
527 |
919 |
528 lemma div_lemma [simp]: |
920 lemma div_lemma [simp]: |
529 "rec_eval rec_quo [x, y] = quo x y" |
921 "rec_eval rec_quo [x, y] = quo x y" |
530 apply(simp add: rec_quo_def quo_def) |
922 apply(simp add: rec_quo_def quo_def) |
531 apply(rule impI) |
923 apply(rule impI) |