9 "HOL-Library.Type_Length" |
9 "HOL-Library.Type_Length" |
10 begin |
10 begin |
11 |
11 |
12 subsection \<open>Truncating bit representations of numeric types\<close> |
12 subsection \<open>Truncating bit representations of numeric types\<close> |
13 |
13 |
14 class semiring_bits = unique_euclidean_semiring_parity + |
14 class semiring_bits = semiring_parity + |
15 assumes semiring_bits: "(1 + 2 * a) mod of_nat (2 * n) = 1 + 2 * (a mod of_nat n)" |
15 assumes semiring_bits: "(1 + 2 * a) mod of_nat (2 * n) = 1 + 2 * (a mod of_nat n)" |
16 begin |
16 begin |
17 |
17 |
18 definition bitrunc :: "nat \<Rightarrow> 'a \<Rightarrow> 'a" |
18 definition bitrunc :: "nat \<Rightarrow> 'a \<Rightarrow> 'a" |
19 where bitrunc_eq_mod: "bitrunc n a = a mod of_nat (2 ^ n)" |
19 where bitrunc_eq_mod: "bitrunc n a = a mod of_nat (2 ^ n)" |
25 lemma bitrunc_0 [simp]: |
25 lemma bitrunc_0 [simp]: |
26 "bitrunc 0 a = 0" |
26 "bitrunc 0 a = 0" |
27 by (simp add: bitrunc_eq_mod) |
27 by (simp add: bitrunc_eq_mod) |
28 |
28 |
29 lemma bitrunc_Suc [simp]: |
29 lemma bitrunc_Suc [simp]: |
30 "bitrunc (Suc n) a = bitrunc n (a div 2) * 2 + a mod 2" |
30 "bitrunc (Suc n) a = bitrunc n (a div 2) * 2 + of_bool (odd a)" |
31 proof - |
31 proof - |
32 define b and c |
32 have "1 + 2 * (a div 2) mod (2 * 2 ^ n) = (a div 2 * 2 + a mod 2) mod (2 * 2 ^ n)" |
33 where "b = a div 2" and "c = a mod 2" |
33 if "odd a" |
34 then have a: "a = b * 2 + c" |
34 using that semiring_bits [of "a div 2" "2 ^ n"] |
35 and "c = 0 \<or> c = 1" |
35 by (simp add: algebra_simps odd_iff_mod_2_eq_one mult_mod_right) |
36 by (simp_all add: div_mult_mod_eq parity) |
36 also have "\<dots> = a mod (2 * 2 ^ n)" |
37 from \<open>c = 0 \<or> c = 1\<close> |
37 by (simp only: div_mult_mod_eq) |
38 have "bitrunc (Suc n) (b * 2 + c) = bitrunc n b * 2 + c" |
38 finally show ?thesis |
39 proof |
39 by (simp add: bitrunc_eq_mod algebra_simps mult_mod_right) |
40 assume "c = 0" |
|
41 moreover have "(2 * b) mod (2 * 2 ^ n) = 2 * (b mod 2 ^ n)" |
|
42 by (simp add: mod_mult_mult1) |
|
43 ultimately show ?thesis |
|
44 by (simp add: bitrunc_eq_mod ac_simps) |
|
45 next |
|
46 assume "c = 1" |
|
47 with semiring_bits [of b "2 ^ n"] show ?thesis |
|
48 by (simp add: bitrunc_eq_mod ac_simps) |
|
49 qed |
|
50 with a show ?thesis |
|
51 by (simp add: b_def c_def) |
|
52 qed |
40 qed |
53 |
41 |
54 lemma bitrunc_of_0 [simp]: |
42 lemma bitrunc_of_0 [simp]: |
55 "bitrunc n 0 = 0" |
43 "bitrunc n 0 = 0" |
56 by (simp add: bitrunc_eq_mod) |
44 by (simp add: bitrunc_eq_mod) |
57 |
45 |
58 lemma bitrunc_plus: |
46 lemma bitrunc_plus: |
59 "bitrunc n (bitrunc n a + bitrunc n b) = bitrunc n (a + b)" |
47 "bitrunc n (bitrunc n a + bitrunc n b) = bitrunc n (a + b)" |
60 by (simp add: bitrunc_eq_mod mod_add_eq) |
48 by (simp add: bitrunc_eq_mod mod_simps) |
61 |
49 |
62 lemma bitrunc_of_1_eq_0_iff [simp]: |
50 lemma bitrunc_of_1_eq_0_iff [simp]: |
63 "bitrunc n 1 = 0 \<longleftrightarrow> n = 0" |
51 "bitrunc n 1 = 0 \<longleftrightarrow> n = 0" |
64 by (induct n) simp_all |
52 by (simp add: bitrunc_eq_mod) |
65 |
53 |
66 end |
54 end |
67 |
55 |
68 instance nat :: semiring_bits |
56 instance nat :: semiring_bits |
69 by standard (simp add: mod_Suc Suc_double_not_eq_double) |
57 by standard (simp add: mod_Suc Suc_double_not_eq_double) |
111 by (simp add: signed_bitrunc_eq_bitrunc odd_iff_mod_2_eq_one) |
99 by (simp add: signed_bitrunc_eq_bitrunc odd_iff_mod_2_eq_one) |
112 qed |
100 qed |
113 |
101 |
114 lemma signed_bitrunc_Suc [simp]: |
102 lemma signed_bitrunc_Suc [simp]: |
115 "signed_bitrunc (Suc n) k = signed_bitrunc n (k div 2) * 2 + k mod 2" |
103 "signed_bitrunc (Suc n) k = signed_bitrunc n (k div 2) * 2 + k mod 2" |
116 using zero_not_eq_two by (simp add: signed_bitrunc_eq_bitrunc algebra_simps) |
104 by (simp add: odd_iff_mod_2_eq_one signed_bitrunc_eq_bitrunc algebra_simps) |
117 |
105 |
118 lemma signed_bitrunc_of_0 [simp]: |
106 lemma signed_bitrunc_of_0 [simp]: |
119 "signed_bitrunc n 0 = 0" |
107 "signed_bitrunc n 0 = 0" |
120 by (simp add: signed_bitrunc_eq_bitrunc bitrunc_eq_mod) |
108 by (simp add: signed_bitrunc_eq_bitrunc bitrunc_eq_mod) |
121 |
109 |