31 |
31 |
32 value "gcd (15::int) (6::int) = 3" |
32 value "gcd (15::int) (6::int) = 3" |
33 value "gcd (10::int) (3::int) = 1" |
33 value "gcd (10::int) (3::int) = 1" |
34 value "gcd (6::int) (24::int) = 6" |
34 value "gcd (6::int) (24::int) = 6" |
35 |
35 |
36 (* why has this been removed since 2002 ? *) |
|
37 definition last_elem :: "'a list \<Rightarrow> 'a" where |
|
38 "last_elem ls = (hd o rev) ls" |
|
39 |
|
40 (* drop tail elements equal 0 *) |
36 (* drop tail elements equal 0 *) |
41 primrec drop_hd_zeros :: "int list \<Rightarrow> int list" where |
37 primrec drop_hd_zeros :: "int list \<Rightarrow> int list" where |
42 "drop_hd_zeros (p # ps) = (if p = 0 then drop_hd_zeros ps else (p # ps))" |
38 "drop_hd_zeros (p # ps) = (if p = 0 then drop_hd_zeros ps else (p # ps))" |
43 definition drop_tl_zeros :: "int list \<Rightarrow> int list" where |
39 definition drop_tl_zeros :: "int list \<Rightarrow> int list" where |
44 "drop_tl_zeros p = (rev o drop_hd_zeros o rev) p" |
40 "drop_tl_zeros p = (rev o drop_hd_zeros o rev) p" |
45 |
41 |
46 subsection {* modulo calculations for integers *} |
42 subsection {* modulo calculations for integers *} |
47 (* modi is just local for mod_inv *) |
43 (* modi is just local for mod_inv *) |
48 function modi :: "int \<Rightarrow> int \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat" where |
44 function modi :: "int \<Rightarrow> int \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat" where |
49 "modi r rold m rinv = |
45 "modi r rold m rinv = |
50 (if m \<le> rinv |
46 (if m \<le> rinv |
51 then 0 else |
47 then 0 else |
52 if r mod (int m) = 1 |
48 if r mod (int m) = 1 |
53 then rinv |
49 then rinv |
54 else modi (rold * ((int rinv) + 1)) rold m (rinv + 1))" |
50 else modi (rold * ((int rinv) + 1)) rold m (rinv + 1))" |
55 by auto |
51 by auto |
56 termination by (relation "measure (\<lambda>(r, rold, m, rinv). m - rinv)") auto |
52 termination by (relation "measure (\<lambda>(r, rold, m, rinv). m - rinv)") auto |
57 |
53 |
58 (* mod_inv :: int \<Rightarrow> nat \<Rightarrow> nat |
54 (* mod_inv :: int \<Rightarrow> nat \<Rightarrow> nat |
59 mod_inv r m = s |
55 mod_inv r m = s |
60 assumes True |
56 assumes True |
61 yields r * s mod m = 1 *) |
57 yields r * s mod m = 1 *) |
62 definition mod_inv :: "int \<Rightarrow> nat \<Rightarrow> nat" where |
58 definition mod_inv :: "int \<Rightarrow> nat \<Rightarrow> nat" where "mod_inv r m = modi r r m 1" |
63 "mod_inv r m = modi r r m 1" |
|
64 |
59 |
65 value "modi 5 5 7 1 = 3" |
60 value "modi 5 5 7 1 = 3" |
66 value "modi 3 3 7 1 = 5" |
61 value "modi 3 3 7 1 = 5" |
67 value "modi 4 4 339 1 = 85" |
62 value "modi 4 4 339 1 = 85" |
68 |
63 |
77 (* mod_div :: int \<Rightarrow> int \<Rightarrow> nat \<Rightarrow> nat |
72 (* mod_div :: int \<Rightarrow> int \<Rightarrow> nat \<Rightarrow> nat |
78 mod_div a b m = c |
73 mod_div a b m = c |
79 assumes True |
74 assumes True |
80 yields a * b ^(-1) mod m = c <\<Longrightarrow> a mod m = *) |
75 yields a * b ^(-1) mod m = c <\<Longrightarrow> a mod m = *) |
81 definition mod_div :: "int \<Rightarrow> int \<Rightarrow> nat \<Rightarrow> nat" where |
76 definition mod_div :: "int \<Rightarrow> int \<Rightarrow> nat \<Rightarrow> nat" where |
82 "mod_div a b m = (nat a) * (mod_inv b m) mod m" |
77 "mod_div a b m = (nat a) * (mod_inv b m) mod m" |
83 |
78 |
84 (* root1 is just local to approx_root *) |
79 (* root1 is just local to approx_root *) |
85 function root1 :: "int \<Rightarrow> nat \<Rightarrow> nat" where |
80 function root1 :: "int \<Rightarrow> nat \<Rightarrow> nat" where |
86 "root1 a n = (if (int (n * n)) < a then root1 a (n + 1) else n)" |
81 "root1 a n = (if (int (n * n)) < a then root1 a (n + 1) else n)" |
87 by auto |
82 by auto |
88 termination by (relation "measure (\<lambda>(a, n). nat (a - (int (n * n))))") auto |
83 termination by (relation "measure (\<lambda>(a, n). nat (a - (int (n * n))))") auto |
89 |
84 |
90 (* required just for one approximation: |
85 (* required just for one approximation: |
91 approx_root :: nat \<Rightarrow> nat |
86 approx_root :: nat \<Rightarrow> nat |
92 approx_root a = r |
87 approx_root a = r |
93 assumes True |
88 assumes True |
94 yields r * r \<ge> a *) |
89 yields r * r \<ge> a *) |
95 definition approx_root :: "int \<Rightarrow> nat" where |
90 definition approx_root :: "int \<Rightarrow> nat" where "approx_root a = root1 a 1" |
96 "approx_root a = root1 a 1" |
|
97 |
91 |
98 (* chinese_remainder :: int \<Rightarrow> int \<Rightarrow> int \<Rightarrow> int \<Rightarrow> int |
92 (* chinese_remainder :: int \<Rightarrow> int \<Rightarrow> int \<Rightarrow> int \<Rightarrow> int |
99 chinese_remainder (r1, m1) (r2, m2) = r |
93 chinese_remainder (r1, m1) (r2, m2) = r |
100 assumes True |
94 assumes True |
101 yields r = r1 mod m1 \<and> r = r2 mod m2 *) |
95 yields r = r1 mod m1 \<and> r = r2 mod m2 *) |
102 definition chinese_remainder :: "int \<Rightarrow> nat \<Rightarrow> int \<Rightarrow> nat \<Rightarrow> nat" where |
96 definition chinese_remainder :: "int \<Rightarrow> nat \<Rightarrow> int \<Rightarrow> nat \<Rightarrow> nat" where |
103 "chinese_remainder r1 m1 r2 m2 = |
97 "chinese_remainder r1 m1 r2 m2 = |
104 ((nat (r1 mod (int m1))) + |
98 ((nat (r1 mod (int m1))) + |
105 (nat (((r2 - (r1 mod (int m1))) * (int (mod_inv (int m1) m2))) mod (int m2))) * m1)" |
99 (nat (((r2 - (r1 mod (int m1))) * (int (mod_inv (int m1) m2))) mod (int m2))) * m1)" |
106 |
100 |
107 value "chinese_remainder 17 9 3 4 = 35" |
101 value "chinese_remainder 17 9 3 4 = 35" |
108 value "chinese_remainder 7 2 6 11 = 17" |
102 value "chinese_remainder 7 2 6 11 = 17" |
109 |
103 |
110 subsection {* creation of lists of primes for efficiency *} |
104 subsection {* creation of lists of primes for efficiency *} |
207 value "primes_upto 9 = [2, 3, 5, 7, 11]" |
201 value "primes_upto 9 = [2, 3, 5, 7, 11]" |
208 value "primes_upto 10 = [2, 3, 5, 7, 11]" |
202 value "primes_upto 10 = [2, 3, 5, 7, 11]" |
209 value "primes_upto 11 = [2, 3, 5, 7, 11]" |
203 value "primes_upto 11 = [2, 3, 5, 7, 11]" |
210 |
204 |
211 (* max's' is analogous to Integer.gcds *) |
205 (* max's' is analogous to Integer.gcds *) |
212 definition maxs :: "nat list \<Rightarrow> nat" where |
206 definition maxs :: "nat list \<Rightarrow> nat" where "maxs ns = List.fold max ns (List.hd ns)" |
213 "maxs ns = List.fold max ns (List.hd ns)" |
207 |
214 value "maxs [5, 3, 7, 1, 2, 4] = 7" |
208 value "maxs [5, 3, 7, 1, 2, 4] = 7" |
215 |
209 |
216 (* find the next prime greater p not dividing the number n: |
210 (* find the next prime greater p not dividing the number n: |
217 next_prime_not_dvd :: int \<Rightarrow> int \<Rightarrow> int (infix) |
211 next_prime_not_dvd :: int \<Rightarrow> int \<Rightarrow> int (infix) |
218 n1 next_prime_not_dvd n2 = p |
212 n1 next_prime_not_dvd n2 = p |
219 assumes True |
213 assumes True |
220 yields p is_prime \<and> n1 < p \<and> \<not> p dvd n2 \<and> (* smallest with these properties... *) |
214 yields p is_prime \<and> n1 < p \<and> \<not> p dvd n2 \<and> (* smallest with these properties... *) |
221 (\<forall> p'. (p' is_prime \<and> n1 < p' \<and> \<not> p' dvd n2) \<longrightarrow> p \<le> p') *) |
215 (\<forall> p'. (p' is_prime \<and> n1 < p' \<and> \<not> p' dvd n2) \<longrightarrow> p \<le> p') *) |
222 function next_prime_not_dvd :: "nat \<Rightarrow> nat \<Rightarrow> nat" (infixl "next'_prime'_not'_dvd" 70) where |
216 function next_prime_not_dvd :: "nat \<Rightarrow> nat \<Rightarrow> nat" (infixl "next'_prime'_not'_dvd" 70) where |
223 "n1 next_prime_not_dvd n2 = |
217 "n1 next_prime_not_dvd n2 = |
224 (let |
218 (let |
225 ps = primes_upto (n1 + 1); |
219 ps = primes_upto (n1 + 1); |
226 nxt = last ps |
220 nxt = last ps |
227 in |
221 in |
228 if n2 mod nxt \<noteq> 0 |
222 if n2 mod nxt \<noteq> 0 |
229 then nxt |
223 then nxt |
230 else nxt next_prime_not_dvd n2)" |
224 else nxt next_prime_not_dvd n2)" |
231 by auto --"simp del: is_prime.simps, make_primes.simps, primes_upto.simps <-- declare" |
225 by auto --"simp del: is_prime.simps, make_primes.simps, primes_upto.simps <-- declare" |
232 termination (*next_prime_not_dvd ..Inner syntax error*) (*not finished*) |
226 termination (*next_prime_not_dvd ..Inner syntax error*) (*not finished*) |
233 apply (relation "measure (\<lambda>(n1, n2). n2 - n1)") |
227 apply (relation "measure (\<lambda>(n1, n2). n2 - n1)") |
234 apply auto |
228 apply auto |
235 sorry (*by lexicographic_order unfinished subgoals*) |
229 sorry (*by lexicographic_order unfinished subgoals*) |
252 |
246 |
253 subsection {* basic notions for univariate polynomials *} |
247 subsection {* basic notions for univariate polynomials *} |
254 |
248 |
255 (* not in List.thy, copy from library.ML *) |
249 (* not in List.thy, copy from library.ML *) |
256 fun nth_drop :: "nat \<Rightarrow> 'a list \<Rightarrow> 'a list" where |
250 fun nth_drop :: "nat \<Rightarrow> 'a list \<Rightarrow> 'a list" where |
257 "nth_drop n xs = List.take n xs @ List.drop (n + 1) xs" |
251 "nth_drop n xs = List.take n xs @ List.drop (n + 1) xs" |
258 value "nth_drop 0 [] = []" |
252 value "nth_drop 0 [] = []" |
259 value "nth_drop 0 [1, 2, 3::int] = [2, 3]" |
253 value "nth_drop 0 [1, 2, 3::int] = [2, 3]" |
260 value "nth_drop 2 [1, 2, 3::int] = [1, 2]" |
254 value "nth_drop 2 [1, 2, 3::int] = [1, 2]" |
261 value "nth_drop 77 [1, 2, 3::int] = [1, 2, 3]" |
255 value "nth_drop 77 [1, 2, 3::int] = [1, 2, 3]" |
262 |
256 |
263 (* leading coefficient *) |
257 (* leading coefficient *) |
264 definition lcoeff_up :: "unipoly \<Rightarrow> int" where |
258 definition lcoeff_up :: "unipoly \<Rightarrow> int" where "lcoeff_up p = (last o drop_tl_zeros) p" |
265 "lcoeff_up p = (last_elem o drop_tl_zeros) p" |
|
266 |
259 |
267 value "lcoeff_up [3, 4, 5, 6] = 6" |
260 value "lcoeff_up [3, 4, 5, 6] = 6" |
268 value "lcoeff_up [3, 4, 5, 6, 0] = 6" |
261 value "lcoeff_up [3, 4, 5, 6, 0] = 6" |
269 |
262 |
270 (* drop leading coefficients equal 0 *) |
263 (* drop leading coefficients equal 0 *) |
335 value "deg_up [3, 4, 5, 6, 0] = 3" |
328 value "deg_up [3, 4, 5, 6, 0] = 3" |
336 value "deg_up [1, 0, 3, 0, 0] = 2" |
329 value "deg_up [1, 0, 3, 0, 0] = 2" |
337 |
330 |
338 (* norm is just local to normalise *) |
331 (* norm is just local to normalise *) |
339 fun norm :: "unipoly \<Rightarrow> unipoly \<Rightarrow> nat \<Rightarrow> int \<Rightarrow> nat \<Rightarrow> unipoly" where |
332 fun norm :: "unipoly \<Rightarrow> unipoly \<Rightarrow> nat \<Rightarrow> int \<Rightarrow> nat \<Rightarrow> unipoly" where |
340 "norm p nrm m lcp i = |
333 "norm p nrm m lcp i = |
341 (if i = 0 |
334 (if i = 0 |
342 then [int (mod_div (p ! i) lcp m)] @ nrm |
335 then [int (mod_div (p ! i) lcp m)] @ nrm |
343 else norm p ([int (mod_div (p ! i) lcp m)] @ nrm) m lcp (i - 1))" |
336 else norm p ([int (mod_div (p ! i) lcp m)] @ nrm) m lcp (i - 1))" |
344 (* normalise a unipoly such that lcoeff_up mod m = 1. |
337 (* normalise a unipoly such that lcoeff_up mod m = 1. |
345 normalise :: unipoly \<Rightarrow> nat \<Rightarrow> unipoly |
338 normalise :: unipoly \<Rightarrow> nat \<Rightarrow> unipoly |
346 normalise [p_0, .., p_k] m = [q_0, .., q_k] |
339 normalise [p_0, .., p_k] m = [q_0, .., q_k] |
347 assumes |
340 assumes |
348 yields \<exists> t. 0 \<le> i \<le> k \<Rightarrow> (p_i * t) mod m = q_i \<and> (p_k * t) mod m = 1 *) |
341 yields \<exists> t. 0 \<le> i \<le> k \<Rightarrow> (p_i * t) mod m = q_i \<and> (p_k * t) mod m = 1 *) |
349 fun normalise :: "unipoly \<Rightarrow> nat \<Rightarrow> unipoly" where |
342 fun normalise :: "unipoly \<Rightarrow> nat \<Rightarrow> unipoly" where |
350 "normalise p m = |
343 "normalise p m = |
351 (let |
344 (let |
352 p = drop_lc0_up p; |
345 p = drop_lc0_up p; |
353 lcp = lcoeff_up p |
346 lcp = lcoeff_up p |
354 in |
347 in |
355 if List.length p = 0 then [] else norm p [] m lcp (List.length p - 1))" |
348 if List.length p = 0 then [] else norm p [] m lcp (List.length p - 1))" |
356 declare normalise.simps [simp del] --"HENSEL_lifting_up" |
349 declare normalise.simps [simp del] --"HENSEL_lifting_up" |
357 |
350 |
358 value "normalise [-18, -15, -20, 12, 20, -13, 2] 5 = [1, 0, 0, 1, 0, 1, 1]" |
351 value "normalise [-18, -15, -20, 12, 20, -13, 2] 5 = [1, 0, 0, 1, 0, 1, 1]" |
359 value "normalise [9, 6, 3] 10 = [3, 2, 1]" |
352 value "normalise [9, 6, 3] 10 = [3, 2, 1]" |
360 |
353 |
361 subsection {* addition, multiplication, division *} |
354 subsection {* addition, multiplication, division *} |
362 |
355 |
363 (* scalar multiplication, %* in GCD_Poly.thy *) |
356 (* scalar multiplication *) |
364 definition mult_ups :: "unipoly \<Rightarrow> int \<Rightarrow> unipoly" (infixl "mult'_ups" 70) where |
357 definition mult_ups :: "unipoly \<Rightarrow> int \<Rightarrow> unipoly" (infixl "%*" 70) where |
365 "p mult_ups m = List.map (op * m) p" |
358 "p %* m = List.map (op * m) p" |
366 |
359 |
367 value "[5, 4, 7, 8, 1] mult_ups 5 = [25, 20, 35, 40, 5]" |
360 value "[5, 4, 7, 8, 1] %* 5 = [25, 20, 35, 40, 5]" |
368 value "[5, 4, -7, 8, -1] mult_ups 5 = [25, 20, -35, 40, -5]" |
361 value "[5, 4, -7, 8, -1] %* 5 = [25, 20, -35, 40, -5]" |
369 |
362 |
370 (* scalar divison, %/ in GCD_Poly.thy *) |
363 (* scalar divison *) |
371 definition swapf :: "('a \<Rightarrow> 'b \<Rightarrow> 'c) \<Rightarrow> 'b \<Rightarrow> 'a \<Rightarrow> 'c" where |
364 definition swapf :: "('a \<Rightarrow> 'b \<Rightarrow> 'c) \<Rightarrow> 'b \<Rightarrow> 'a \<Rightarrow> 'c" where "swapf f a b = f b a" |
372 "swapf f a b = f b a" |
365 definition div_ups :: "unipoly \<Rightarrow> int \<Rightarrow> unipoly" (infixl "div'_ups" (* %/ error FLORIAN*) 70) where |
373 definition div_ups :: "unipoly \<Rightarrow> int \<Rightarrow> unipoly" (infixl "div'_ups" 70) where |
366 "p div_ups m = map (swapf op div2 m) p" |
374 "p div_ups m = map (swapf op div2 m) p" |
|
375 |
367 |
376 value "[4, 3, 2, 5, 6] div_ups 3 = [1, 1, 0, 1, 2]" |
368 value "[4, 3, 2, 5, 6] div_ups 3 = [1, 1, 0, 1, 2]" |
377 value "[4, 3, 2, 0] div_ups 3 = [1, 1, 0, 0]" |
369 value "[4, 3, 2, 0] div_ups 3 = [1, 1, 0, 0]" |
378 |
370 |
379 (* not in List.thy, copy from library.ML *) |
371 (* not in List.thy, copy from library.ML *) |
380 fun map2 :: "('a \<Rightarrow> 'b \<Rightarrow> 'c) \<Rightarrow> 'a list \<Rightarrow> 'b list \<Rightarrow> 'c list" where |
372 fun map2 :: "('a \<Rightarrow> 'b \<Rightarrow> 'c) \<Rightarrow> 'a list \<Rightarrow> 'b list \<Rightarrow> 'c list" where |
381 "map2 _ [] [] = []" |
373 "map2 _ [] [] = []" | |
382 | "map2 f (x # xs) (y # ys) = f x y # map2 f xs ys" |
374 "map2 f (x # xs) (y # ys) = f x y # map2 f xs ys" | |
383 | "map2 _ _ _ = []" (*raise ListPair.UnequalLengths*) |
375 "map2 _ _ _ = []" (*raise ListPair.UnequalLengths*) |
384 |
376 |
385 (* minus of polys, %-% in GCD_Poly.thy *) |
377 (* minus of polys *) |
386 definition minus_up :: "unipoly \<Rightarrow> unipoly \<Rightarrow> unipoly" (infixl "minus'_up" 70) where |
378 definition minus_up :: "unipoly \<Rightarrow> unipoly \<Rightarrow> unipoly" (infixl "%-%" 70) where |
387 "p1 minus_up p2 = map2 (op -) p1 p2" |
379 "p1 %-% p2 = map2 (op -) p1 p2" |
388 |
380 |
389 value "[8, -7, 0, 1] minus_up [-2, 2, 3, 0] = [10, -9, -3, 1]" |
381 value "[8, -7, 0, 1] %-% [-2, 2, 3, 0] = [10, -9, -3, 1]" |
390 value "[8, 7, 6, 5, 4] minus_up [2, 2, 3, 1, 1] = [6, 5, 3, 4, 3]" |
382 value "[8, 7, 6, 5, 4] %-% [2, 2, 3, 1, 1] = [6, 5, 3, 4, 3]" |
391 |
383 |
392 (* lemmata for pattern compatibility in dvd_up *) |
384 (* lemmata for pattern compatibility in dvd_up *) |
393 lemma ex_fals0_1: "([d], [p]) = (v # vb # vc, ps) \<Longrightarrow> QUODLIBET" |
385 lemma ex_fals0_1: "([d], [p]) = (v # vb # vc, ps) \<Longrightarrow> QUODLIBET" by simp |
394 by simp |
386 lemma ex_fals0_2: "([], ps) = (v # vb # vc, psa) \<Longrightarrow> QUODLIBET" by simp |
395 lemma ex_fals0_2: "([], ps) = (v # vb # vc, psa) \<Longrightarrow> QUODLIBET" |
387 lemma ex_fals0_3: "(ds, []) = (dsa, v # vb # vc) \<Longrightarrow> QUODLIBET" by simp |
396 by simp |
388 |
397 lemma ex_fals0_3: "(ds, []) = (dsa, v # vb # vc) \<Longrightarrow> QUODLIBET" |
389 function (sequential) dvd_up :: "unipoly \<Rightarrow> unipoly \<Rightarrow> bool" (infixl "%|%" 70) where |
398 by simp |
390 "[d] %|% [p] = ((\<bar>d\<bar> \<le> \<bar>p\<bar>) & (p mod d = 0))" | |
399 |
391 "ds %|% ps = |
400 function (sequential) dvd_up :: "unipoly \<Rightarrow> unipoly \<Rightarrow> bool" (infixl "dvd'_up" 70) where |
392 (let |
401 "[d] dvd_up [p] = ((\<bar>d\<bar> \<le> \<bar>p\<bar>) & (p mod d = 0))" |
393 ds = drop_lc0_up ds; ps = drop_lc0_up ps; |
402 | "ds dvd_up ps = |
394 d000 = (List.replicate (List.length ps - List.length ds) 0) @ ds; |
403 (let |
395 quot = (lcoeff_up ps) div2 (lcoeff_up d000); |
404 ds = drop_lc0_up ds; ps = drop_lc0_up ps; |
396 rest = drop_lc0_up (ps %-% (d000 %* quot)) |
405 d000 = (List.replicate (List.length ps - List.length ds) 0) @ ds; |
397 in |
406 quot = (lcoeff_up ps) div2 (lcoeff_up d000); |
398 if rest = [] then True else |
407 rest = drop_lc0_up (ps minus_up (d000 mult_ups quot)) |
399 if quot \<noteq> 0 & List.length ds \<le> List.length rest then ds %|% rest else False)" |
408 in |
|
409 if rest = [] then True else |
|
410 if quot \<noteq> 0 & List.length ds \<le> List.length rest then ds dvd_up rest else False)" |
|
411 apply pat_completeness |
400 apply pat_completeness |
412 apply simp |
401 apply simp |
413 apply simp |
402 apply simp |
414 defer (*a "mixed" obligation*) |
403 defer (*a "mixed" obligation*) |
415 apply simp |
404 apply simp |
439 done (* > 1 sec IMPROVED BY declare simp del: |
428 done (* > 1 sec IMPROVED BY declare simp del: |
440 centr_up_def normalise.simps mod_up_gcd.simps lcoeff_up.simps*) |
429 centr_up_def normalise.simps mod_up_gcd.simps lcoeff_up.simps*) |
441 termination (*dvd_up ..Inner syntax error*) sorry (*by lexicographic_order LOOPS*) (*not finished*) |
430 termination (*dvd_up ..Inner syntax error*) sorry (*by lexicographic_order LOOPS*) (*not finished*) |
442 (*cutting definition to 'fun' loops, so no Calls, Measure, Matrix ---?*) |
431 (*cutting definition to 'fun' loops, so no Calls, Measure, Matrix ---?*) |
443 |
432 |
444 value "[4] dvd_up [6] = False" |
433 value "[4] %|% [6] = False" |
445 value "[8] dvd_up [16, 0] = True" |
434 value "[8] %|% [16, 0] = True" |
446 value "[3, 2] dvd_up [0, 0, 9, 12, 4] = True" |
435 value "[3, 2] %|% [0, 0, 9, 12, 4] = True" |
447 value "[8, 0] dvd_up [16] = True" |
436 value "[8, 0] %|% [16] = True" |
448 |
437 |
449 subsection {* normalisation and Landau-Mignotte bound *} |
438 subsection {* normalisation and Landau-Mignotte bound *} |
450 |
439 |
451 (* centr is just local to centr_up *) |
440 (* centr is just local to centr_up *) |
452 definition centr :: "nat \<Rightarrow> int \<Rightarrow> int \<Rightarrow> int" where |
441 definition centr :: "nat \<Rightarrow> int \<Rightarrow> int \<Rightarrow> int" where |
453 "centr m mid p_i = (if mid < p_i then p_i - (int m) else p_i)" |
442 "centr m mid p_i = (if mid < p_i then p_i - (int m) else p_i)" |
454 |
443 |
455 (* normalise :: centr_up \<Rightarrow> unipoly => int \<Rightarrow> unipoly |
444 (* normalise :: centr_up \<Rightarrow> unipoly => int \<Rightarrow> unipoly |
456 normalise [p_0, .., p_k] m = [q_0, .., q_k] |
445 normalise [p_0, .., p_k] m = [q_0, .., q_k] |
457 assumes |
446 assumes |
458 yields 0 \<le> i \<le> k \<Rightarrow> |^ ~m/2 ^| <= q_i <=|^ m/2 ^| |
447 yields 0 \<le> i \<le> k \<Rightarrow> |^ ~m/2 ^| <= q_i <=|^ m/2 ^| |
459 (where |^ x ^| means round x up to the next greater integer) *) |
448 (where |^ x ^| means round x up to the next greater integer) *) |
460 definition centr_up :: "unipoly \<Rightarrow> nat \<Rightarrow> unipoly" where |
449 definition centr_up :: "unipoly \<Rightarrow> nat \<Rightarrow> unipoly" where |
461 "centr_up p m = |
450 "centr_up p m = |
462 (let |
451 (let |
463 mi = (int m) div2 2; |
452 mi = (int m) div2 2; |
464 mid = if (int m) mod mi = 0 then mi else mi + 1 |
453 mid = if (int m) mod mi = 0 then mi else mi + 1 |
465 in map (centr m mid) p)" |
454 in map (centr m mid) p)" |
466 |
455 |
467 value "centr_up [7, 3, 5, 8, 1, 3] 10 = [-3, 3, 5, -2, 1, 3]" |
456 value "centr_up [7, 3, 5, 8, 1, 3] 10 = [-3, 3, 5, -2, 1, 3]" |
468 value "centr_up [1, 2, 3, 4, 5] 2 = [1, 0, 1, 2, 3]" |
457 value "centr_up [1, 2, 3, 4, 5] 2 = [1, 0, 1, 2, 3]" |
469 value "centr_up [1, 2, 3, 4, 5] 3 = [1, -1, 0, 1, 2]" |
458 value "centr_up [1, 2, 3, 4, 5] 3 = [1, -1, 0, 1, 2]" |
470 value "centr_up [1, 2, 3, 4, 5] 4 = [1, 2, -1, 0, 1]" |
459 value "centr_up [1, 2, 3, 4, 5] 4 = [1, 2, -1, 0, 1]" |
474 value "centr_up [1, 2, 3, 4, 5] 8 = [1, 2, 3, 4, -3]" |
463 value "centr_up [1, 2, 3, 4, 5] 8 = [1, 2, 3, 4, -3]" |
475 value "centr_up [1, 2, 3, 4, 5] 9 = [1, 2, 3, 4, 5]" |
464 value "centr_up [1, 2, 3, 4, 5] 9 = [1, 2, 3, 4, 5]" |
476 value "centr_up [1, 2, 3, 4, 5] 10 = [1, 2, 3, 4, 5]" |
465 value "centr_up [1, 2, 3, 4, 5] 10 = [1, 2, 3, 4, 5]" |
477 value "centr_up [1, 2, 3, 4, 5] 11 = [1, 2, 3, 4, 5]" |
466 value "centr_up [1, 2, 3, 4, 5] 11 = [1, 2, 3, 4, 5]" |
478 |
467 |
479 (* sum_lmb :: centr_up \<Rightarrow> unipoly \<Rightarrow> int \<Rightarrow> int |
468 (* sum_lmb :: centr_up \<Rightarrow> unipoly \<Rightarrow> int \<Rightarrow> int |
480 sum_lmb [p_0, .., p_k] e = s |
469 sum_lmb [p_0, .., p_k] e = s |
481 assumes exp >= 0 |
470 assumes exp >= 0 |
482 yields. p_0^e + p_1^e + ... + p_k^e *) |
471 yields. p_0^e + p_1^e + ... + p_k^e *) |
483 definition sum_lmb :: "unipoly \<Rightarrow> nat \<Rightarrow> int" where |
472 definition sum_lmb :: "unipoly \<Rightarrow> nat \<Rightarrow> int" where |
484 "sum_lmb p exp = List.fold ((op +) o (swapf power exp)) p 0" |
473 "sum_lmb p exp = List.fold ((op +) o (swapf power exp)) p 0" |
485 |
474 |
486 value "sum_lmb [-1, 2, -3, 4, -5] 1 = -3" |
475 value "sum_lmb [-1, 2, -3, 4, -5] 1 = -3" |
487 value "sum_lmb [-1, 2, -3, 4, -5] 2 = 55" |
476 value "sum_lmb [-1, 2, -3, 4, -5] 2 = 55" |
488 value "sum_lmb [-1, 2, -3, 4, -5] 3 = -81" |
477 value "sum_lmb [-1, 2, -3, 4, -5] 3 = -81" |
489 value "sum_lmb [-1, 2, -3, 4, -5] 4 = 979" |
478 value "sum_lmb [-1, 2, -3, 4, -5] 4 = 979" |
494 LANDAU_MIGNOTTE_bound [a_0, ..., a_m] [b_0, .., b_n] = lmb |
483 LANDAU_MIGNOTTE_bound [a_0, ..., a_m] [b_0, .., b_n] = lmb |
495 assumes True |
484 assumes True |
496 yields lmb = 2^min(m,n) * gcd(a_m,b_n) * |
485 yields lmb = 2^min(m,n) * gcd(a_m,b_n) * |
497 min( 1/|a_m| * root(sum_lmb [a_0,...a_m] 2 , 1/|b_n| * root(sum_lmb [b_0,...b_n] 2)*) |
486 min( 1/|a_m| * root(sum_lmb [a_0,...a_m] 2 , 1/|b_n| * root(sum_lmb [b_0,...b_n] 2)*) |
498 definition LANDAU_MIGNOTTE_bound :: "unipoly \<Rightarrow> unipoly \<Rightarrow> nat" where |
487 definition LANDAU_MIGNOTTE_bound :: "unipoly \<Rightarrow> unipoly \<Rightarrow> nat" where |
499 "LANDAU_MIGNOTTE_bound p1 p2 = |
488 "LANDAU_MIGNOTTE_bound p1 p2 = |
500 ((power 2 (min (deg_up p1) (deg_up p2))) * (nat (gcd (lcoeff_up p1) (lcoeff_up p2))) * |
489 ((power 2 (min (deg_up p1) (deg_up p2))) * (nat (gcd (lcoeff_up p1) (lcoeff_up p2))) * |
501 (nat (min (abs ((int (approx_root (sum_lmb p1 2))) div2 -(lcoeff_up p1))) |
490 (nat (min (abs ((int (approx_root (sum_lmb p1 2))) div2 -(lcoeff_up p1))) |
502 (abs ((int (approx_root (sum_lmb p2 2))) div2 -(lcoeff_up p2))))))" |
491 (abs ((int (approx_root (sum_lmb p2 2))) div2 -(lcoeff_up p2))))))" |
503 (* |------------| -|------------| |
|
504 |--------------------------| |
|
505 |--------------------------------| |
|
506 |-------------------------------------------------------| *) |
|
507 |
492 |
508 value "LANDAU_MIGNOTTE_bound [1] [4, 5] = 1" |
493 value "LANDAU_MIGNOTTE_bound [1] [4, 5] = 1" |
509 value "LANDAU_MIGNOTTE_bound [1, 2] [4, 5] = 2" |
494 value "LANDAU_MIGNOTTE_bound [1, 2] [4, 5] = 2" |
510 value "LANDAU_MIGNOTTE_bound [1, 2, 3] [4, 5] = 2" |
495 value "LANDAU_MIGNOTTE_bound [1, 2, 3] [4, 5] = 2" |
511 value "LANDAU_MIGNOTTE_bound [1, 2, 3] [4] = 1" |
496 value "LANDAU_MIGNOTTE_bound [1, 2, 3] [4] = 1" |
518 value "LANDAU_MIGNOTTE_bound [-1, 2, -3] [4] = 1" |
503 value "LANDAU_MIGNOTTE_bound [-1, 2, -3] [4] = 1" |
519 value "LANDAU_MIGNOTTE_bound [-1, 2, -3] [4, -5] = 2" |
504 value "LANDAU_MIGNOTTE_bound [-1, 2, -3] [4, -5] = 2" |
520 value "LANDAU_MIGNOTTE_bound [-1, 2, -3] [4, -5, 6] = 12" |
505 value "LANDAU_MIGNOTTE_bound [-1, 2, -3] [4, -5, 6] = 12" |
521 |
506 |
522 subsection {* modulo calculations for polynomials *} |
507 subsection {* modulo calculations for polynomials *} |
|
508 value "List.compound" |
523 |
509 |
524 (* pair is just local to chinese_remainder_up, is "op ~~" in library.ML *) |
510 (* pair is just local to chinese_remainder_up, is "op ~~" in library.ML *) |
525 fun pair :: "unipoly \<Rightarrow> unipoly \<Rightarrow> ((int \<times> int) list)" (infix "pair" 4) where |
511 fun pair :: "unipoly \<Rightarrow> unipoly \<Rightarrow> ((int \<times> int) list)" (infix "pair" 4) where |
526 "([] pair []) = []" |
512 "([] pair []) = []" | |
527 | "([] pair ys) = []" (*raise ListPair.UnequalLengths*) |
513 "([] pair ys) = []" | (*raise ListPair.UnequalLengths*) |
528 | "(xs pair []) = []" (*raise ListPair.UnequalLengths*) |
514 "(xs pair []) = []" | (*raise ListPair.UnequalLengths*) |
529 | "((x#xs) pair (y#ys)) = (x, y) # (xs pair ys)" |
515 "((x#xs) pair (y#ys)) = (x, y) # (xs pair ys)" |
530 fun chinese_rem :: "nat \<times> nat \<Rightarrow> int \<times> int \<Rightarrow> int" where |
516 fun chinese_rem :: "nat \<times> nat \<Rightarrow> int \<times> int \<Rightarrow> int" where |
531 "chinese_rem (m1, m2) (p1, p2) = (int (chinese_remainder p1 m1 p2 m2))" |
517 "chinese_rem (m1, m2) (p1, p2) = (int (chinese_remainder p1 m1 p2 m2))" |
532 |
518 |
533 (* chinese_remainder_up :: int * int \<Rightarrow> unipoly * unipoly \<Rightarrow> unipoly |
519 (* chinese_remainder_up :: int * int \<Rightarrow> unipoly * unipoly \<Rightarrow> unipoly |
534 chinese_remainder_up (m1, m2) (p1, p2) = p |
520 chinese_remainder_up (m1, m2) (p1, p2) = p |
535 assume m1, m2 relatively prime |
521 assume m1, m2 relatively prime |
536 yields p1 = p mod m1 \<and> p2 = p mod m2 *) |
522 yields p1 = p mod m1 \<and> p2 = p mod m2 *) |
537 fun chinese_remainder_up :: "nat \<times> nat \<Rightarrow> unipoly \<times> unipoly \<Rightarrow> unipoly" where |
523 fun chinese_remainder_up :: "nat \<times> nat \<Rightarrow> unipoly \<times> unipoly \<Rightarrow> unipoly" where |
538 "chinese_remainder_up (m1, m2) (p1, p2) = map (chinese_rem (m1, m2)) (p1 pair p2)" |
524 "chinese_remainder_up (m1, m2) (p1, p2) = map (chinese_rem (m1, m2)) (p1 pair p2)" |
539 |
525 |
540 value "chinese_remainder_up (5, 7) ([2, 2, 4, 3], [3, 2, 3, 5]) = [17, 2, 24, 33]" |
526 value "chinese_remainder_up (5, 7) ([2, 2, 4, 3], [3, 2, 3, 5]) = [17, 2, 24, 33]" |
541 |
527 |
542 (* mod_up :: unipoly \<Rightarrow> int \<Rightarrow> unipoly |
528 (* mod_up :: unipoly \<Rightarrow> int \<Rightarrow> unipoly |
543 mod_up [p1, p2, ..., pk] m = up |
529 mod_up [p1, p2, ..., pk] m = up |
544 assume m > 0 |
530 assume m > 0 |
545 yields up = [p1 mod m, p2 mod m, ..., pk mod m]*) |
531 yields up = [p1 mod m, p2 mod m, ..., pk mod m]*) |
546 definition mod' :: "nat \<Rightarrow> int \<Rightarrow> int" where "mod' m i = i mod (int m)" |
532 definition mod' :: "nat \<Rightarrow> int \<Rightarrow> int" where "mod' m i = i mod (int m)" |
547 definition mod_up :: "unipoly \<Rightarrow> nat \<Rightarrow> unipoly" (infixl "mod'_up" 70) where |
533 definition mod_up :: "unipoly \<Rightarrow> nat \<Rightarrow> unipoly" (infixl "mod'_up" 70) where |
548 "p mod_up m = map (mod' m) p" |
534 "p mod_up m = map (mod' m) p" |
549 |
535 |
550 value "[5, 4, 7, 8, 1] mod_up 5 = [0, 4, 2, 3, 1]" |
536 value "[5, 4, 7, 8, 1] mod_up 5 = [0, 4, 2, 3, 1]" |
551 value "[5, 4,-7, 8,-1] mod_up 5 = [0, 4, 3, 3, 4]" |
537 value "[5, 4,-7, 8,-1] mod_up 5 = [0, 4, 3, 3, 4]" |
552 |
|
553 value "curry" |
|
554 value "curry" |
|
555 value "5 mod 3::int" |
|
556 |
|
557 |
538 |
558 (* euclidean algoritm in Z_p[x]. |
539 (* euclidean algoritm in Z_p[x]. |
559 mod_up_gcd :: unipoly \<Rightarrow> unipoly \<Rightarrow> nat \<Rightarrow> unipoly |
540 mod_up_gcd :: unipoly \<Rightarrow> unipoly \<Rightarrow> nat \<Rightarrow> unipoly |
560 mod_up_gcd p1 p2 m = g |
541 mod_up_gcd p1 p2 m = g |
561 assumes |
542 assumes |
562 yields gcd (p1 mod m) (p2 mod m) = g *) |
543 yields gcd (p1 mod m) (p2 mod m) = g *) |
563 function mod_up_gcd :: "unipoly \<Rightarrow> unipoly \<Rightarrow> nat \<Rightarrow> unipoly" where |
544 function mod_up_gcd :: "unipoly \<Rightarrow> unipoly \<Rightarrow> nat \<Rightarrow> unipoly" where |
564 "mod_up_gcd p1 p2 m = |
545 "mod_up_gcd p1 p2 m = |
565 (let |
546 (let |
566 p1m = p1 mod_up m; |
547 p1m = p1 mod_up m; |
567 p2m = drop_lc0_up (p2 mod_up m); |
548 p2m = drop_lc0_up (p2 mod_up m); |
568 p2n = (replicate (List.length p1 - List.length p2m) 0) @ p2m; |
549 p2n = (replicate (List.length p1 - List.length p2m) 0) @ p2m; |
569 quot = mod_div (lcoeff_up p1m) (lcoeff_up p2n) m; |
550 quot = mod_div (lcoeff_up p1m) (lcoeff_up p2n) m; |
570 rest = drop_lc0_up ((p1m minus_up (p2n mult_ups (int quot))) mod_up m) |
551 rest = drop_lc0_up ((p1m %-% (p2n %* (int quot))) mod_up m) |
571 in |
552 in |
572 if rest = [] |
553 if rest = [] |
573 then p2 |
554 then p2 |
574 else |
555 else |
575 if List.length rest < List.length p2 |
556 if List.length rest < List.length p2 |
576 then mod_up_gcd p2 rest m |
557 then mod_up_gcd p2 rest m |
577 else mod_up_gcd rest p2 m)" |
558 else mod_up_gcd rest p2 m)" |
578 by auto |
559 by auto |
579 termination mod_up_gcd (*not finished*) |
560 termination mod_up_gcd (*not finished*) |
580 apply (relation "measures [\<lambda>(p1, p2, m). length p1, |
561 apply (relation "measures [\<lambda>(p1, p2, m). length p1, |
581 \<lambda>(p1, p2, m). 00000000000000]") |
562 \<lambda>(p1, p2, m). 00000000000000]") |
582 apply auto |
563 apply auto |
641 yields new_g = [1] \<or> (new_g \<ge> g \<and> P > M) |
621 yields new_g = [1] \<or> (new_g \<ge> g \<and> P > M) |
642 |
622 |
643 argumentns "a b d M P g p" named according to [1] p.93 *) |
623 argumentns "a b d M P g p" named according to [1] p.93 *) |
644 (*declare [[show_types]]*) |
624 (*declare [[show_types]]*) |
645 function try_new_prime_up :: "unipoly \<Rightarrow> unipoly \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> unipoly \<Rightarrow> nat \<Rightarrow> unipoly" |
625 function try_new_prime_up :: "unipoly \<Rightarrow> unipoly \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> unipoly \<Rightarrow> nat \<Rightarrow> unipoly" |
646 where |
626 where |
647 "try_new_prime_up a b d M P g p = |
627 "try_new_prime_up a b d M P g p = |
648 (if P > M then g else |
628 (if P > M then g else |
649 let p' = p next_prime_not_dvd d; |
629 let p' = p next_prime_not_dvd d; |
650 g_p = centr_up ( ( (normalise (mod_up_gcd a b p') p') |
630 g_p = centr_up ( ( (normalise (mod_up_gcd a b p') p') |
651 mult_ups ((int d) mod (int p'))) |
631 %* ((int d) mod (int p'))) |
652 mod_up p') |
632 mod_up p') |
653 p' |
633 p' |
654 in |
634 in |
655 if deg_up g_p < deg_up g |
635 if deg_up g_p < deg_up g |
656 then |
636 then |
657 if (deg_up g_p) = 0 then [1] else try_new_prime_up a b d M p g_p p' |
637 if (deg_up g_p) = 0 then [1] else try_new_prime_up a b d M p g_p p' |
658 else |
638 else |
659 if deg_up g_p \<noteq> deg_up g then try_new_prime_up a b d M P g p' else |
639 if deg_up g_p \<noteq> deg_up g then try_new_prime_up a b d M P g p' else |
660 let |
640 let |
661 P = P * p'; |
641 P = P * p'; |
662 g = centr_up ((chinese_remainder_up (P, p') (g, g_p)) mod_up P) P |
642 g = centr_up ((chinese_remainder_up (P, p') (g, g_p)) mod_up P) P |
663 in |
643 in |
664 try_new_prime_up a b d M P g p' |
644 try_new_prime_up a b d M P g p')" |
665 )" |
|
666 by pat_completeness auto --"simp del: centr_up_def normalise.simps mod_up_gcd.simps" |
645 by pat_completeness auto --"simp del: centr_up_def normalise.simps mod_up_gcd.simps" |
667 termination try_new_prime_up sorry (*by lexicographic_order LOOPS*) (*not finished*) |
646 termination try_new_prime_up sorry (*by lexicographic_order LOOPS*) (*not finished*) |
668 (*cutting definition to 'fun' loops, so no Calls, Measure, Matrix ---?*) |
647 (*cutting definition to 'fun' loops, so no Calls, Measure, Matrix ---?*) |
669 |
648 |
670 (* HENSEL_lifting_up :: unipoly \<Rightarrow> unipoly \<Rightarrow> int \<Rightarrow> int \<Rightarrow> int \<Rightarrow> unipoly |
649 (* HENSEL_lifting_up :: unipoly \<Rightarrow> unipoly \<Rightarrow> int \<Rightarrow> int \<Rightarrow> int \<Rightarrow> unipoly |
674 p1 is primitive \<and> p2 is primitive |
653 p1 is primitive \<and> p2 is primitive |
675 yields gcd | p1 \<and> gcd | p2 \<and> gcd is primitive |
654 yields gcd | p1 \<and> gcd | p2 \<and> gcd is primitive |
676 |
655 |
677 argumentns "a b d M p" named according to [1] p.93 *) |
656 argumentns "a b d M p" named according to [1] p.93 *) |
678 function HENSEL_lifting_up :: "unipoly \<Rightarrow> unipoly \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> unipoly" where |
657 function HENSEL_lifting_up :: "unipoly \<Rightarrow> unipoly \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> unipoly" where |
679 "HENSEL_lifting_up a b d M p = |
658 "HENSEL_lifting_up a b d M p = |
680 (let |
659 (let |
681 p = p next_prime_not_dvd d; |
660 p = p next_prime_not_dvd d; |
682 g_p = centr_up (((normalise (mod_up_gcd a b p) p) mult_ups (int (d mod p))) mod_up p) p |
661 g_p = centr_up (((normalise (mod_up_gcd a b p) p) %* (int (d mod p))) mod_up p) p |
683 in |
662 in |
684 if deg_up g_p = 0 then [1] else |
663 if deg_up g_p = 0 then [1] else |
685 (let |
664 (let |
686 g = primitive_up (try_new_prime_up a b d M p g_p p) |
665 g = primitive_up (try_new_prime_up a b d M p g_p p) |
687 in |
666 in |
688 if (g dvd_up a) \<and> (g dvd_up b) then g else HENSEL_lifting_up a b d M p))" |
667 if (g %|% a) \<and> (g %|% b) then g else HENSEL_lifting_up a b d M p))" |
689 by pat_completeness auto --"simp del: centr_up_def normalise.simps mod_up_gcd.simps" |
668 by pat_completeness auto --"simp del: centr_up_def normalise.simps mod_up_gcd.simps" |
690 termination HENSEL_lifting_up sorry (*by lexicographic_order LOOPS*) (*not finished*) |
669 termination HENSEL_lifting_up sorry (*by lexicographic_order LOOPS*) (*not finished*) |
691 (*cutting definition to 'fun' loops, so no Calls, Measure, Matrix ---?*) |
670 (*cutting definition to 'fun' loops, so no Calls, Measure, Matrix ---?*) |
692 |
671 |
693 (* gcd_up :: unipoly \<Rightarrow> unipoly \<Rightarrow> unipoly |
672 (* gcd_up :: unipoly \<Rightarrow> unipoly \<Rightarrow> unipoly |
694 gcd_up a b = c |
673 gcd_up a b = c |
695 assumes not (a = [] \<or> a = [0]) \<and> not (b = []\<or> b = [0]) \<and> |
674 assumes not (a = [] \<or> a = [0]) \<and> not (b = []\<or> b = [0]) \<and> |
696 a is primitive \<and> b is primitive |
675 a is primitive \<and> b is primitive |
697 yields c dvd a \<and> c dvd b \<and> (\<forall>c'. (c' dvd a \<and> c' dvd b) \<longrightarrow> c' \<le> c) *) |
676 yields c dvd a \<and> c dvd b \<and> (\<forall>c'. (c' dvd a \<and> c' dvd b) \<longrightarrow> c' \<le> c) *) |
698 function gcd_up :: "unipoly \<Rightarrow> unipoly \<Rightarrow> unipoly" where |
677 function gcd_up :: "unipoly \<Rightarrow> unipoly \<Rightarrow> unipoly" where |
699 "gcd_up a b = |
678 "gcd_up a b = |
700 (let d = \<bar>gcd (lcoeff_up a) (lcoeff_up b)\<bar> |
679 (let d = \<bar>gcd (lcoeff_up a) (lcoeff_up b)\<bar> |
701 in |
680 in |
702 if a = b then a else |
681 if a = b then a else |
703 HENSEL_lifting_up a b (nat d) (2 * (nat d) * LANDAU_MIGNOTTE_bound a b) 1)" |
682 HENSEL_lifting_up a b (nat d) (2 * (nat d) * LANDAU_MIGNOTTE_bound a b) 1)" |
704 by pat_completeness auto --"simp del: lcoeff_up.simps ?+ others?" |
683 by pat_completeness auto --"simp del: lcoeff_up.simps ?+ others?" |
705 termination by lexicographic_order (*works*) |
684 termination by lexicographic_order (*works*) |
706 |
685 |
707 value "gcd_up [-18, -15, -20, 12, 20, -13, 2] [8, 28, 22, -11, -14, 1, 2] = [-2, -1, 1]" |
686 value "gcd_up [-18, -15, -20, 12, 20, -13, 2] [8, 28, 22, -11, -14, 1, 2] = [-2, -1, 1]" |
708 (* gcd (-1 + x^2) (x + x^2) = (1 + x) *) |
687 (* gcd (-1 + x^2) (x + x^2) = (1 + x) *) |
709 value "gcd_up [-1, 0 ,1] [0, 1, 1] = [1, 1]" |
688 value "gcd_up [-1, 0 ,1] [0, 1, 1] = [1, 1]" |
710 |
|
711 primrec nth :: "'a list => nat => 'a" (infixl "!!" 100) where |
|
712 nth_Cons: "(x # xs) !! n = (case n of 0 \<Rightarrow> x | Suc k \<Rightarrow> xs !! k)" |
|
713 value "[1,2,3,4,5] ! 2" |
|
714 |
|
715 definition mult_ups2 :: "unipoly \<Rightarrow> int \<Rightarrow> unipoly" (infixl "%*" 70) where |
|
716 "p %* m = List.map (op * m) p" |
|
717 |
689 |
718 (* |
690 (* |
719 print_configs |
691 print_configs |
720 declare [[simp_trace_depth_limit = 99]] |
692 declare [[simp_trace_depth_limit = 99]] |
721 declare [[simp_trace = true]] |
693 declare [[simp_trace = true]] |