11 |
11 |
12 subsection \<open>Ring structures with parity and \<open>even\<close>/\<open>odd\<close> predicates\<close> |
12 subsection \<open>Ring structures with parity and \<open>even\<close>/\<open>odd\<close> predicates\<close> |
13 |
13 |
14 class semiring_parity = linordered_semidom + unique_euclidean_semiring + |
14 class semiring_parity = linordered_semidom + unique_euclidean_semiring + |
15 assumes of_nat_div: "of_nat (m div n) = of_nat m div of_nat n" |
15 assumes of_nat_div: "of_nat (m div n) = of_nat m div of_nat n" |
16 and odd_imp_mod_2_eq_1: "\<not> 2 dvd a \<Longrightarrow> a mod 2 = 1" |
16 and division_segment_of_nat [simp]: "division_segment (of_nat n) = 1" |
17 |
17 and division_segment_euclidean_size [simp]: "division_segment a * of_nat (euclidean_size a) = a" |
18 context semiring_parity |
|
19 begin |
18 begin |
|
19 |
|
20 lemma division_segment_eq_iff: |
|
21 "a = b" if "division_segment a = division_segment b" |
|
22 and "euclidean_size a = euclidean_size b" |
|
23 using that division_segment_euclidean_size [of a] by simp |
|
24 |
|
25 lemma euclidean_size_of_nat [simp]: |
|
26 "euclidean_size (of_nat n) = n" |
|
27 proof - |
|
28 have "division_segment (of_nat n) * of_nat (euclidean_size (of_nat n)) = of_nat n" |
|
29 by (fact division_segment_euclidean_size) |
|
30 then show ?thesis by simp |
|
31 qed |
|
32 |
|
33 lemma of_nat_euclidean_size: |
|
34 "of_nat (euclidean_size a) = a div division_segment a" |
|
35 proof - |
|
36 have "of_nat (euclidean_size a) = division_segment a * of_nat (euclidean_size a) div division_segment a" |
|
37 by (subst nonzero_mult_div_cancel_left) simp_all |
|
38 also have "\<dots> = a div division_segment a" |
|
39 by simp |
|
40 finally show ?thesis . |
|
41 qed |
|
42 |
|
43 lemma division_segment_1 [simp]: |
|
44 "division_segment 1 = 1" |
|
45 using division_segment_of_nat [of 1] by simp |
|
46 |
|
47 lemma division_segment_numeral [simp]: |
|
48 "division_segment (numeral k) = 1" |
|
49 using division_segment_of_nat [of "numeral k"] by simp |
|
50 |
|
51 lemma euclidean_size_1 [simp]: |
|
52 "euclidean_size 1 = 1" |
|
53 using euclidean_size_of_nat [of 1] by simp |
|
54 |
|
55 lemma euclidean_size_numeral [simp]: |
|
56 "euclidean_size (numeral k) = numeral k" |
|
57 using euclidean_size_of_nat [of "numeral k"] by simp |
20 |
58 |
21 lemma of_nat_dvd_iff: |
59 lemma of_nat_dvd_iff: |
22 "of_nat m dvd of_nat n \<longleftrightarrow> m dvd n" (is "?P \<longleftrightarrow> ?Q") |
60 "of_nat m dvd of_nat n \<longleftrightarrow> m dvd n" (is "?P \<longleftrightarrow> ?Q") |
23 proof (cases "m = 0") |
61 proof (cases "m = 0") |
24 case True |
62 case True |
84 "even a \<longleftrightarrow> a mod 2 = 0" |
122 "even a \<longleftrightarrow> a mod 2 = 0" |
85 by (fact dvd_eq_mod_eq_0) |
123 by (fact dvd_eq_mod_eq_0) |
86 |
124 |
87 lemma odd_iff_mod_2_eq_one: |
125 lemma odd_iff_mod_2_eq_one: |
88 "odd a \<longleftrightarrow> a mod 2 = 1" |
126 "odd a \<longleftrightarrow> a mod 2 = 1" |
89 by (auto dest: odd_imp_mod_2_eq_1) |
127 proof |
|
128 assume "a mod 2 = 1" |
|
129 then show "odd a" |
|
130 by auto |
|
131 next |
|
132 assume "odd a" |
|
133 have eucl: "euclidean_size (a mod 2) = 1" |
|
134 proof (rule order_antisym) |
|
135 show "euclidean_size (a mod 2) \<le> 1" |
|
136 using mod_size_less [of 2 a] by simp |
|
137 show "1 \<le> euclidean_size (a mod 2)" |
|
138 proof (rule ccontr) |
|
139 assume "\<not> 1 \<le> euclidean_size (a mod 2)" |
|
140 then have "euclidean_size (a mod 2) = 0" |
|
141 by simp |
|
142 then have "division_segment (a mod 2) * of_nat (euclidean_size (a mod 2)) = division_segment (a mod 2) * of_nat 0" |
|
143 by simp |
|
144 with \<open>odd a\<close> show False |
|
145 by (simp add: dvd_eq_mod_eq_0) |
|
146 qed |
|
147 qed |
|
148 from \<open>odd a\<close> have "\<not> of_nat 2 dvd division_segment a * of_nat (euclidean_size a)" |
|
149 by simp |
|
150 then have "\<not> of_nat 2 dvd of_nat (euclidean_size a)" |
|
151 by (auto simp only: dvd_mult_unit_iff' is_unit_division_segment) |
|
152 then have "\<not> 2 dvd euclidean_size a" |
|
153 using of_nat_dvd_iff [of 2] by simp |
|
154 then have "euclidean_size a mod 2 = 1" |
|
155 by (simp add: semidom_modulo_class.dvd_eq_mod_eq_0) |
|
156 then have "of_nat (euclidean_size a mod 2) = of_nat 1" |
|
157 by simp |
|
158 then have "of_nat (euclidean_size a) mod 2 = 1" |
|
159 by (simp add: of_nat_mod) |
|
160 from \<open>odd a\<close> eucl |
|
161 show "a mod 2 = 1" |
|
162 by (auto intro: division_segment_eq_iff simp add: division_segment_mod) |
|
163 qed |
90 |
164 |
91 lemma parity_cases [case_names even odd]: |
165 lemma parity_cases [case_names even odd]: |
92 assumes "even a \<Longrightarrow> a mod 2 = 0 \<Longrightarrow> P" |
166 assumes "even a \<Longrightarrow> a mod 2 = 0 \<Longrightarrow> P" |
93 assumes "odd a \<Longrightarrow> a mod 2 = 1 \<Longrightarrow> P" |
167 assumes "odd a \<Longrightarrow> a mod 2 = 1 \<Longrightarrow> P" |
94 shows P |
168 shows P |
485 |
559 |
486 |
560 |
487 subsection \<open>Instance for @{typ int}\<close> |
561 subsection \<open>Instance for @{typ int}\<close> |
488 |
562 |
489 instance int :: ring_parity |
563 instance int :: ring_parity |
490 proof |
564 by standard (simp_all add: dvd_eq_mod_eq_0 divide_int_def division_segment_int_def) |
491 fix k l :: int |
|
492 show "k mod 2 = 1" if "\<not> 2 dvd k" |
|
493 proof (rule order_antisym) |
|
494 have "0 \<le> k mod 2" and "k mod 2 < 2" |
|
495 by auto |
|
496 moreover have "k mod 2 \<noteq> 0" |
|
497 using that by (simp add: dvd_eq_mod_eq_0) |
|
498 ultimately have "0 < k mod 2" |
|
499 by (simp only: less_le) simp |
|
500 then show "1 \<le> k mod 2" |
|
501 by simp |
|
502 from \<open>k mod 2 < 2\<close> show "k mod 2 \<le> 1" |
|
503 by (simp only: less_le) simp |
|
504 qed |
|
505 qed (simp_all add: dvd_eq_mod_eq_0 divide_int_def) |
|
506 |
565 |
507 lemma even_diff_iff [simp]: |
566 lemma even_diff_iff [simp]: |
508 "even (k - l) \<longleftrightarrow> even (k + l)" for k l :: int |
567 "even (k - l) \<longleftrightarrow> even (k + l)" for k l :: int |
509 using dvd_add_times_triv_right_iff [of 2 "k - l" l] by (simp add: mult_2_right) |
568 using dvd_add_times_triv_right_iff [of 2 "k - l" l] by (simp add: mult_2_right) |
510 |
569 |