17 to its positive segments. This is its primary motivation, and it |
17 to its positive segments. This is its primary motivation, and it |
18 could surely be formulated using a more fine-grained, more algebraic |
18 could surely be formulated using a more fine-grained, more algebraic |
19 and less technical class hierarchy. |
19 and less technical class hierarchy. |
20 \<close> |
20 \<close> |
21 |
21 |
22 class unique_euclidean_semiring_numeral = unique_euclidean_semiring + linordered_semidom + |
22 class unique_euclidean_semiring_numeral = semiring_parity + linordered_semidom + |
23 assumes div_less: "0 \<le> a \<Longrightarrow> a < b \<Longrightarrow> a div b = 0" |
23 assumes div_less: "0 \<le> a \<Longrightarrow> a < b \<Longrightarrow> a div b = 0" |
24 and mod_less: " 0 \<le> a \<Longrightarrow> a < b \<Longrightarrow> a mod b = a" |
24 and mod_less: " 0 \<le> a \<Longrightarrow> a < b \<Longrightarrow> a mod b = a" |
25 and div_positive: "0 < b \<Longrightarrow> b \<le> a \<Longrightarrow> a div b > 0" |
25 and div_positive: "0 < b \<Longrightarrow> b \<le> a \<Longrightarrow> a div b > 0" |
26 and mod_less_eq_dividend: "0 \<le> a \<Longrightarrow> a mod b \<le> a" |
26 and mod_less_eq_dividend: "0 \<le> a \<Longrightarrow> a mod b \<le> a" |
27 and pos_mod_bound: "0 < b \<Longrightarrow> a mod b < b" |
27 and pos_mod_bound: "0 < b \<Longrightarrow> a mod b < b" |
38 \<comment> \<open>These are conceptually definitions but force generated code |
38 \<comment> \<open>These are conceptually definitions but force generated code |
39 to be monomorphic wrt. particular instances of this class which |
39 to be monomorphic wrt. particular instances of this class which |
40 yields a significant speedup.\<close> |
40 yields a significant speedup.\<close> |
41 begin |
41 begin |
42 |
42 |
43 subclass unique_euclidean_semiring_parity |
|
44 proof |
|
45 fix a |
|
46 show "a mod 2 = 0 \<or> a mod 2 = 1" |
|
47 proof (rule ccontr) |
|
48 assume "\<not> (a mod 2 = 0 \<or> a mod 2 = 1)" |
|
49 then have "a mod 2 \<noteq> 0" and "a mod 2 \<noteq> 1" by simp_all |
|
50 have "0 < 2" by simp |
|
51 with pos_mod_bound pos_mod_sign have "0 \<le> a mod 2" "a mod 2 < 2" by simp_all |
|
52 with \<open>a mod 2 \<noteq> 0\<close> have "0 < a mod 2" by simp |
|
53 with discrete have "1 \<le> a mod 2" by simp |
|
54 with \<open>a mod 2 \<noteq> 1\<close> have "1 < a mod 2" by simp |
|
55 with discrete have "2 \<le> a mod 2" by simp |
|
56 with \<open>a mod 2 < 2\<close> show False by simp |
|
57 qed |
|
58 next |
|
59 show "1 mod 2 = 1" |
|
60 by (rule mod_less) simp_all |
|
61 next |
|
62 show "0 \<noteq> 2" |
|
63 by simp |
|
64 qed |
|
65 |
|
66 lemma divmod_digit_1: |
43 lemma divmod_digit_1: |
67 assumes "0 \<le> a" "0 < b" and "b \<le> a mod (2 * b)" |
44 assumes "0 \<le> a" "0 < b" and "b \<le> a mod (2 * b)" |
68 shows "2 * (a div (2 * b)) + 1 = a div b" (is "?P") |
45 shows "2 * (a div (2 * b)) + 1 = a div b" (is "?P") |
69 and "a mod (2 * b) - b = a mod b" (is "?Q") |
46 and "a mod (2 * b) - b = a mod b" (is "?Q") |
70 proof - |
47 proof - |
72 by (auto intro: trans) |
49 by (auto intro: trans) |
73 with \<open>0 < b\<close> have "0 < a div b" by (auto intro: div_positive) |
50 with \<open>0 < b\<close> have "0 < a div b" by (auto intro: div_positive) |
74 then have [simp]: "1 \<le> a div b" by (simp add: discrete) |
51 then have [simp]: "1 \<le> a div b" by (simp add: discrete) |
75 with \<open>0 < b\<close> have mod_less: "a mod b < b" by (simp add: pos_mod_bound) |
52 with \<open>0 < b\<close> have mod_less: "a mod b < b" by (simp add: pos_mod_bound) |
76 define w where "w = a div b mod 2" |
53 define w where "w = a div b mod 2" |
77 with parity have w_exhaust: "w = 0 \<or> w = 1" by auto |
54 then have w_exhaust: "w = 0 \<or> w = 1" by auto |
78 have mod_w: "a mod (2 * b) = a mod b + b * w" |
55 have mod_w: "a mod (2 * b) = a mod b + b * w" |
79 by (simp add: w_def mod_mult2_eq ac_simps) |
56 by (simp add: w_def mod_mult2_eq ac_simps) |
80 from assms w_exhaust have "w = 1" |
57 from assms w_exhaust have "w = 1" |
81 by (auto simp add: mod_w) (insert mod_less, auto) |
58 by (auto simp add: mod_w) (insert mod_less, auto) |
82 with mod_w have mod: "a mod (2 * b) = a mod b + b" by simp |
59 with mod_w have mod: "a mod (2 * b) = a mod b + b" by simp |
91 assumes "0 < b" and "a mod (2 * b) < b" |
68 assumes "0 < b" and "a mod (2 * b) < b" |
92 shows "2 * (a div (2 * b)) = a div b" (is "?P") |
69 shows "2 * (a div (2 * b)) = a div b" (is "?P") |
93 and "a mod (2 * b) = a mod b" (is "?Q") |
70 and "a mod (2 * b) = a mod b" (is "?Q") |
94 proof - |
71 proof - |
95 define w where "w = a div b mod 2" |
72 define w where "w = a div b mod 2" |
96 with parity have w_exhaust: "w = 0 \<or> w = 1" by auto |
73 then have w_exhaust: "w = 0 \<or> w = 1" by auto |
97 have mod_w: "a mod (2 * b) = a mod b + b * w" |
74 have mod_w: "a mod (2 * b) = a mod b + b * w" |
98 by (simp add: w_def mod_mult2_eq ac_simps) |
75 by (simp add: w_def mod_mult2_eq ac_simps) |
99 moreover have "b \<le> a mod b + b" |
76 moreover have "b \<le> a mod b + b" |
100 proof - |
77 proof - |
101 from \<open>0 < b\<close> pos_mod_sign have "0 \<le> a mod b" by blast |
78 from \<open>0 < b\<close> pos_mod_sign have "0 \<le> a mod b" by blast |
316 |
293 |
317 end |
294 end |
318 |
295 |
319 declare divmod_algorithm_code [where ?'a = nat, code] |
296 declare divmod_algorithm_code [where ?'a = nat, code] |
320 |
297 |
321 lemma odd_Suc_minus_one [simp]: "odd n \<Longrightarrow> Suc (n - Suc 0) = n" |
|
322 by (auto elim: oddE) |
|
323 |
|
324 lemma even_Suc_div_two [simp]: |
|
325 "even n \<Longrightarrow> Suc n div 2 = n div 2" |
|
326 using even_succ_div_two [of n] by simp |
|
327 |
|
328 lemma odd_Suc_div_two [simp]: |
|
329 "odd n \<Longrightarrow> Suc n div 2 = Suc (n div 2)" |
|
330 using odd_succ_div_two [of n] by simp |
|
331 |
|
332 lemma odd_two_times_div_two_nat [simp]: |
|
333 assumes "odd n" |
|
334 shows "2 * (n div 2) = n - (1 :: nat)" |
|
335 proof - |
|
336 from assms have "2 * (n div 2) + 1 = n" |
|
337 by (rule odd_two_times_div_two_succ) |
|
338 then have "Suc (2 * (n div 2)) - 1 = n - 1" |
|
339 by simp |
|
340 then show ?thesis |
|
341 by simp |
|
342 qed |
|
343 |
|
344 lemma parity_induct [case_names zero even odd]: |
|
345 assumes zero: "P 0" |
|
346 assumes even: "\<And>n. P n \<Longrightarrow> P (2 * n)" |
|
347 assumes odd: "\<And>n. P n \<Longrightarrow> P (Suc (2 * n))" |
|
348 shows "P n" |
|
349 proof (induct n rule: less_induct) |
|
350 case (less n) |
|
351 show "P n" |
|
352 proof (cases "n = 0") |
|
353 case True with zero show ?thesis by simp |
|
354 next |
|
355 case False |
|
356 with less have hyp: "P (n div 2)" by simp |
|
357 show ?thesis |
|
358 proof (cases "even n") |
|
359 case True |
|
360 with hyp even [of "n div 2"] show ?thesis |
|
361 by simp |
|
362 next |
|
363 case False |
|
364 with hyp odd [of "n div 2"] show ?thesis |
|
365 by simp |
|
366 qed |
|
367 qed |
|
368 qed |
|
369 |
|
370 lemma mod_2_not_eq_zero_eq_one_nat: |
|
371 fixes n :: nat |
|
372 shows "n mod 2 \<noteq> 0 \<longleftrightarrow> n mod 2 = 1" |
|
373 by (fact not_mod_2_eq_0_eq_1) |
|
374 |
|
375 lemma Suc_0_div_numeral [simp]: |
298 lemma Suc_0_div_numeral [simp]: |
376 fixes k l :: num |
299 fixes k l :: num |
377 shows "Suc 0 div numeral k = fst (divmod Num.One k)" |
300 shows "Suc 0 div numeral k = fst (divmod Num.One k)" |
378 by (simp_all add: fst_divmod) |
301 by (simp_all add: fst_divmod) |
379 |
302 |
705 apply (rule_tac q = "-1" in mod_int_unique) |
628 apply (rule_tac q = "-1" in mod_int_unique) |
706 apply (auto simp add: eucl_rel_int_iff) |
629 apply (auto simp add: eucl_rel_int_iff) |
707 done |
630 done |
708 |
631 |
709 text\<open>There is no \<open>mod_neg_pos_trivial\<close>.\<close> |
632 text\<open>There is no \<open>mod_neg_pos_trivial\<close>.\<close> |
|
633 |
|
634 instance int :: ring_parity |
|
635 proof |
|
636 fix k l :: int |
|
637 show "k mod 2 = 1" if "\<not> 2 dvd k" |
|
638 proof (rule order_antisym) |
|
639 have "0 \<le> k mod 2" and "k mod 2 < 2" |
|
640 by auto |
|
641 moreover have "k mod 2 \<noteq> 0" |
|
642 using that by (simp add: dvd_eq_mod_eq_0) |
|
643 ultimately have "0 < k mod 2" |
|
644 by (simp only: less_le) simp |
|
645 then show "1 \<le> k mod 2" |
|
646 by simp |
|
647 from \<open>k mod 2 < 2\<close> show "k mod 2 \<le> 1" |
|
648 by (simp only: less_le) simp |
|
649 qed |
|
650 qed (simp_all add: dvd_eq_mod_eq_0 divide_int_def) |
|
651 |
|
652 lemma even_diff_iff [simp]: |
|
653 "even (k - l) \<longleftrightarrow> even (k + l)" for k l :: int |
|
654 using dvd_add_times_triv_right_iff [of 2 "k - l" l] by (simp add: mult_2_right) |
|
655 |
|
656 lemma even_abs_add_iff [simp]: |
|
657 "even (\<bar>k\<bar> + l) \<longleftrightarrow> even (k + l)" for k l :: int |
|
658 by (cases "k \<ge> 0") (simp_all add: ac_simps) |
|
659 |
|
660 lemma even_add_abs_iff [simp]: |
|
661 "even (k + \<bar>l\<bar>) \<longleftrightarrow> even (k + l)" for k l :: int |
|
662 using even_abs_add_iff [of l k] by (simp add: ac_simps) |
|
663 |
|
664 lemma even_nat_iff: "0 \<le> k \<Longrightarrow> even (nat k) \<longleftrightarrow> even k" |
|
665 by (simp add: even_of_nat [of "nat k", where ?'a = int, symmetric]) |
710 |
666 |
711 |
667 |
712 subsubsection \<open>Laws for div and mod with Unary Minus\<close> |
668 subsubsection \<open>Laws for div and mod with Unary Minus\<close> |
713 |
669 |
714 lemma zminus1_lemma: |
670 lemma zminus1_lemma: |
1493 from div_mult_mod_eq obtain q where "q * d + m mod d = m" by blast |
1449 from div_mult_mod_eq obtain q where "q * d + m mod d = m" by blast |
1494 with assms have "m = r + q * d" by simp |
1450 with assms have "m = r + q * d" by simp |
1495 then show ?thesis .. |
1451 then show ?thesis .. |
1496 qed |
1452 qed |
1497 |
1453 |
|
1454 lemmas even_times_iff = even_mult_iff -- \<open>FIXME duplicate\<close> |
|
1455 |
|
1456 lemma mod_2_not_eq_zero_eq_one_nat: |
|
1457 fixes n :: nat |
|
1458 shows "n mod 2 \<noteq> 0 \<longleftrightarrow> n mod 2 = 1" |
|
1459 by (fact not_mod_2_eq_0_eq_1) |
|
1460 |
|
1461 lemma even_int_iff [simp]: "even (int n) \<longleftrightarrow> even n" |
|
1462 by (fact even_of_nat) |
|
1463 |
|
1464 text \<open>Tool setup\<close> |
|
1465 |
|
1466 declare transfer_morphism_int_nat [transfer add return: even_int_iff] |
|
1467 |
1498 end |
1468 end |