5 section \<open>A type of finite bit strings\<close> |
5 section \<open>A type of finite bit strings\<close> |
6 |
6 |
7 theory Word |
7 theory Word |
8 imports |
8 imports |
9 "HOL-Library.Type_Length" |
9 "HOL-Library.Type_Length" |
10 "HOL-Library.Boolean_Algebra" |
|
11 "HOL-Library.Bit_Operations" |
|
12 begin |
10 begin |
13 |
11 |
14 subsection \<open>Preliminaries\<close> |
12 subsection \<open>Preliminaries\<close> |
15 |
13 |
16 lemma signed_take_bit_decr_length_iff: |
14 lemma signed_take_bit_decr_length_iff: |
1129 proof (cases \<open>n \<le> m\<close>) |
1127 proof (cases \<open>n \<le> m\<close>) |
1130 case True |
1128 case True |
1131 with \<open>2 ^ m \<noteq> 0\<close> have \<open>2 ^ (m - n) \<noteq> 0\<close> |
1129 with \<open>2 ^ m \<noteq> 0\<close> have \<open>2 ^ (m - n) \<noteq> 0\<close> |
1132 by (metis (full_types) diff_add exp_add_not_zero_imp) |
1130 by (metis (full_types) diff_add exp_add_not_zero_imp) |
1133 with True show ?thesis |
1131 with True show ?thesis |
1134 by (simp add: bit_unsigned_iff bit_push_bit_iff Parity.bit_push_bit_iff bit_take_bit_iff not_le exp_eq_zero_iff ac_simps) |
1132 by (simp add: bit_unsigned_iff bit_push_bit_iff Bit_Operations.bit_push_bit_iff bit_take_bit_iff not_le ac_simps) |
1135 next |
1133 next |
1136 case False |
1134 case False |
1137 then show ?thesis |
1135 then show ?thesis |
1138 by (simp add: not_le bit_unsigned_iff bit_push_bit_iff Parity.bit_push_bit_iff bit_take_bit_iff) |
1136 by (simp add: not_le bit_unsigned_iff bit_push_bit_iff Bit_Operations.bit_push_bit_iff bit_take_bit_iff) |
1139 qed |
1137 qed |
1140 qed |
1138 qed |
1141 |
1139 |
1142 lemma unsigned_take_bit_eq: |
1140 lemma unsigned_take_bit_eq: |
1143 \<open>unsigned (take_bit n w) = take_bit n (unsigned w)\<close> |
1141 \<open>unsigned (take_bit n w) = take_bit n (unsigned w)\<close> |
1144 for w :: \<open>'b::len word\<close> |
1142 for w :: \<open>'b::len word\<close> |
1145 by (rule bit_eqI) (simp add: bit_unsigned_iff bit_take_bit_iff Parity.bit_take_bit_iff) |
1143 by (rule bit_eqI) (simp add: bit_unsigned_iff bit_take_bit_iff Bit_Operations.bit_take_bit_iff) |
1146 |
1144 |
1147 end |
1145 end |
1148 |
1146 |
1149 context unique_euclidean_semiring_with_bit_shifts |
1147 context unique_euclidean_semiring_with_bit_shifts |
1150 begin |
1148 begin |
1151 |
1149 |
1152 lemma unsigned_drop_bit_eq: |
1150 lemma unsigned_drop_bit_eq: |
1153 \<open>unsigned (drop_bit n w) = drop_bit n (take_bit LENGTH('b) (unsigned w))\<close> |
1151 \<open>unsigned (drop_bit n w) = drop_bit n (take_bit LENGTH('b) (unsigned w))\<close> |
1154 for w :: \<open>'b::len word\<close> |
1152 for w :: \<open>'b::len word\<close> |
1155 by (rule bit_eqI) (auto simp add: bit_unsigned_iff bit_take_bit_iff bit_drop_bit_eq Parity.bit_drop_bit_eq dest: bit_imp_le_length) |
1153 by (rule bit_eqI) (auto simp add: bit_unsigned_iff bit_take_bit_iff bit_drop_bit_eq Bit_Operations.bit_drop_bit_eq dest: bit_imp_le_length) |
1156 |
1154 |
1157 end |
1155 end |
1158 |
1156 |
1159 lemma ucast_drop_bit_eq: |
1157 lemma ucast_drop_bit_eq: |
1160 \<open>ucast (drop_bit n w) = drop_bit n (ucast w :: 'b::len word)\<close> |
1158 \<open>ucast (drop_bit n w) = drop_bit n (ucast w :: 'b::len word)\<close> |
1262 using exp_add_not_zero_imp_left [of q r] exp_add_not_zero_imp_right [of q r] |
1260 using exp_add_not_zero_imp_left [of q r] exp_add_not_zero_imp_right [of q r] |
1263 by simp_all |
1261 by simp_all |
1264 moreover from \<open>2 ^ q \<noteq> 0\<close> have \<open>2 ^ (q - n) \<noteq> 0\<close> |
1262 moreover from \<open>2 ^ q \<noteq> 0\<close> have \<open>2 ^ (q - n) \<noteq> 0\<close> |
1265 by (rule exp_not_zero_imp_exp_diff_not_zero) |
1263 by (rule exp_not_zero_imp_exp_diff_not_zero) |
1266 ultimately show ?thesis |
1264 ultimately show ?thesis |
1267 by (auto simp add: bit_signed_iff bit_signed_take_bit_iff bit_push_bit_iff Parity.bit_push_bit_iff |
1265 by (auto simp add: bit_signed_iff bit_signed_take_bit_iff bit_push_bit_iff Bit_Operations.bit_push_bit_iff |
1268 min_def * exp_eq_zero_iff le_diff_conv2) |
1266 min_def * le_diff_conv2) |
1269 next |
1267 next |
1270 case False |
1268 case False |
1271 then show ?thesis |
1269 then show ?thesis |
1272 using exp_not_zero_imp_exp_diff_not_zero [of m n] |
1270 using exp_not_zero_imp_exp_diff_not_zero [of m n] |
1273 by (auto simp add: bit_signed_iff bit_signed_take_bit_iff bit_push_bit_iff Parity.bit_push_bit_iff |
1271 by (auto simp add: bit_signed_iff bit_signed_take_bit_iff bit_push_bit_iff Bit_Operations.bit_push_bit_iff |
1274 min_def not_le not_less * le_diff_conv2 less_diff_conv2 Parity.exp_eq_0_imp_not_bit exp_eq_0_imp_not_bit |
1272 min_def not_le not_less * le_diff_conv2 less_diff_conv2 Bit_Operations.exp_eq_0_imp_not_bit exp_eq_0_imp_not_bit) |
1275 exp_eq_zero_iff) |
|
1276 qed |
1273 qed |
1277 qed |
1274 qed |
1278 |
1275 |
1279 lemma signed_take_bit_eq: |
1276 lemma signed_take_bit_eq: |
1280 \<open>signed (take_bit n w) = (if n < LENGTH('b) then take_bit n (signed w) else signed w)\<close> |
1277 \<open>signed (take_bit n w) = (if n < LENGTH('b) then take_bit n (signed w) else signed w)\<close> |
1300 by simp |
1297 by simp |
1301 moreover from \<open>2 ^ n \<noteq> 0\<close> \<open>n = r + Suc q\<close> |
1298 moreover from \<open>2 ^ n \<noteq> 0\<close> \<open>n = r + Suc q\<close> |
1302 have \<open>2 ^ Suc q \<noteq> 0\<close> |
1299 have \<open>2 ^ Suc q \<noteq> 0\<close> |
1303 using exp_add_not_zero_imp_right by blast |
1300 using exp_add_not_zero_imp_right by blast |
1304 ultimately show ?thesis |
1301 ultimately show ?thesis |
1305 by (simp add: * bit_signed_iff bit_not_iff bit_signed_take_bit_iff Bit_Operations.bit_not_iff min_def |
1302 by (simp add: * bit_signed_iff bit_not_iff bit_signed_take_bit_iff Bit_Operations.bit_not_iff min_def) |
1306 exp_eq_zero_iff) |
|
1307 next |
1303 next |
1308 case False |
1304 case False |
1309 then show ?thesis |
1305 then show ?thesis |
1310 by (auto simp add: * bit_signed_iff bit_not_iff bit_signed_take_bit_iff Bit_Operations.bit_not_iff min_def |
1306 by (auto simp add: * bit_signed_iff bit_not_iff bit_signed_take_bit_iff Bit_Operations.bit_not_iff min_def) |
1311 exp_eq_zero_iff) |
|
1312 qed |
1307 qed |
1313 qed |
1308 qed |
1314 |
1309 |
1315 context |
1310 context |
1316 includes bit_operations_syntax |
1311 includes bit_operations_syntax |
1409 begin |
1404 begin |
1410 |
1405 |
1411 lemma unsigned_ucast_eq: |
1406 lemma unsigned_ucast_eq: |
1412 \<open>unsigned (ucast w :: 'c::len word) = take_bit LENGTH('c) (unsigned w)\<close> |
1407 \<open>unsigned (ucast w :: 'c::len word) = take_bit LENGTH('c) (unsigned w)\<close> |
1413 for w :: \<open>'b::len word\<close> |
1408 for w :: \<open>'b::len word\<close> |
1414 by (rule bit_eqI) (simp add: bit_unsigned_iff Word.bit_unsigned_iff bit_take_bit_iff exp_eq_zero_iff not_le) |
1409 by (rule bit_eqI) (simp add: bit_unsigned_iff Word.bit_unsigned_iff bit_take_bit_iff not_le) |
1415 |
1410 |
1416 end |
1411 end |
1417 |
1412 |
1418 context ring_bit_operations |
1413 context ring_bit_operations |
1419 begin |
1414 begin |
1426 assume \<open>2 ^ n \<noteq> 0\<close> |
1421 assume \<open>2 ^ n \<noteq> 0\<close> |
1427 then have \<open>2 ^ (min (LENGTH('c) - Suc 0) n) \<noteq> 0\<close> |
1422 then have \<open>2 ^ (min (LENGTH('c) - Suc 0) n) \<noteq> 0\<close> |
1428 by (simp add: min_def) |
1423 by (simp add: min_def) |
1429 (metis (mono_tags) diff_diff_cancel exp_not_zero_imp_exp_diff_not_zero) |
1424 (metis (mono_tags) diff_diff_cancel exp_not_zero_imp_exp_diff_not_zero) |
1430 then show \<open>bit (signed (ucast w :: 'c::len word)) n \<longleftrightarrow> bit (signed_take_bit (LENGTH('c) - Suc 0) (unsigned w)) n\<close> |
1425 then show \<open>bit (signed (ucast w :: 'c::len word)) n \<longleftrightarrow> bit (signed_take_bit (LENGTH('c) - Suc 0) (unsigned w)) n\<close> |
1431 by (simp add: bit_signed_iff bit_unsigned_iff Word.bit_unsigned_iff bit_signed_take_bit_iff exp_eq_zero_iff not_le) |
1426 by (simp add: bit_signed_iff bit_unsigned_iff Word.bit_unsigned_iff bit_signed_take_bit_iff not_le) |
1432 qed |
1427 qed |
1433 |
1428 |
1434 lemma signed_scast_eq: |
1429 lemma signed_scast_eq: |
1435 \<open>signed (scast w :: 'c::len word) = signed_take_bit (LENGTH('c) - Suc 0) (signed w)\<close> |
1430 \<open>signed (scast w :: 'c::len word) = signed_take_bit (LENGTH('c) - Suc 0) (signed w)\<close> |
1436 for w :: \<open>'b::len word\<close> |
1431 for w :: \<open>'b::len word\<close> |
1439 assume \<open>2 ^ n \<noteq> 0\<close> |
1434 assume \<open>2 ^ n \<noteq> 0\<close> |
1440 then have \<open>2 ^ (min (LENGTH('c) - Suc 0) n) \<noteq> 0\<close> |
1435 then have \<open>2 ^ (min (LENGTH('c) - Suc 0) n) \<noteq> 0\<close> |
1441 by (simp add: min_def) |
1436 by (simp add: min_def) |
1442 (metis (mono_tags) diff_diff_cancel exp_not_zero_imp_exp_diff_not_zero) |
1437 (metis (mono_tags) diff_diff_cancel exp_not_zero_imp_exp_diff_not_zero) |
1443 then show \<open>bit (signed (scast w :: 'c::len word)) n \<longleftrightarrow> bit (signed_take_bit (LENGTH('c) - Suc 0) (signed w)) n\<close> |
1438 then show \<open>bit (signed (scast w :: 'c::len word)) n \<longleftrightarrow> bit (signed_take_bit (LENGTH('c) - Suc 0) (signed w)) n\<close> |
1444 by (simp add: bit_signed_iff bit_unsigned_iff Word.bit_signed_iff bit_signed_take_bit_iff exp_eq_zero_iff not_le) |
1439 by (simp add: bit_signed_iff bit_unsigned_iff Word.bit_signed_iff bit_signed_take_bit_iff not_le) |
1445 qed |
1440 qed |
1446 |
1441 |
1447 end |
1442 end |
1448 |
1443 |
1449 lemma uint_nonnegative: "0 \<le> uint w" |
1444 lemma uint_nonnegative: "0 \<le> uint w" |
2102 lemma uint_word_rotr_eq: |
2097 lemma uint_word_rotr_eq: |
2103 \<open>uint (word_rotr n w) = concat_bit (LENGTH('a) - n mod LENGTH('a)) |
2098 \<open>uint (word_rotr n w) = concat_bit (LENGTH('a) - n mod LENGTH('a)) |
2104 (drop_bit (n mod LENGTH('a)) (uint w)) |
2099 (drop_bit (n mod LENGTH('a)) (uint w)) |
2105 (uint (take_bit (n mod LENGTH('a)) w))\<close> |
2100 (uint (take_bit (n mod LENGTH('a)) w))\<close> |
2106 for w :: \<open>'a::len word\<close> |
2101 for w :: \<open>'a::len word\<close> |
2107 apply transfer |
2102 by transfer (simp add: take_bit_concat_bit_eq) |
2108 by (simp add: min.absorb2 take_bit_concat_bit_eq) |
|
2109 |
2103 |
2110 lemma [code]: |
2104 lemma [code]: |
2111 \<open>Word.the_int (word_rotr n w) = concat_bit (LENGTH('a) - n mod LENGTH('a)) |
2105 \<open>Word.the_int (word_rotr n w) = concat_bit (LENGTH('a) - n mod LENGTH('a)) |
2112 (drop_bit (n mod LENGTH('a)) (Word.the_int w)) |
2106 (drop_bit (n mod LENGTH('a)) (Word.the_int w)) |
2113 (Word.the_int (take_bit (n mod LENGTH('a)) w))\<close> |
2107 (Word.the_int (take_bit (n mod LENGTH('a)) w))\<close> |
2345 \<open>cast\<close> -- note, no arg for new length, as it's determined by type of result, |
2339 \<open>cast\<close> -- note, no arg for new length, as it's determined by type of result, |
2346 thus in \<open>cast w = w\<close>, the type means cast to length of \<open>w\<close>! |
2340 thus in \<open>cast w = w\<close>, the type means cast to length of \<open>w\<close>! |
2347 \<close> |
2341 \<close> |
2348 |
2342 |
2349 lemma bit_ucast_iff: |
2343 lemma bit_ucast_iff: |
2350 \<open>bit (ucast a :: 'a::len word) n \<longleftrightarrow> n < LENGTH('a::len) \<and> Parity.bit a n\<close> |
2344 \<open>bit (ucast a :: 'a::len word) n \<longleftrightarrow> n < LENGTH('a::len) \<and> bit a n\<close> |
2351 by transfer (simp add: bit_take_bit_iff) |
2345 by transfer (simp add: bit_take_bit_iff) |
2352 |
2346 |
2353 lemma ucast_id [simp]: "ucast w = w" |
2347 lemma ucast_id [simp]: "ucast w = w" |
2354 by transfer simp |
2348 by transfer simp |
2355 |
2349 |
2356 lemma scast_id [simp]: "scast w = w" |
2350 lemma scast_id [simp]: "scast w = w" |
2357 by transfer (simp add: take_bit_signed_take_bit) |
2351 by transfer (simp add: take_bit_signed_take_bit) |
2358 |
2352 |
2359 lemma ucast_mask_eq: |
2353 lemma ucast_mask_eq: |
2360 \<open>ucast (mask n :: 'b word) = mask (min LENGTH('b::len) n)\<close> |
2354 \<open>ucast (mask n :: 'b word) = mask (min LENGTH('b::len) n)\<close> |
2361 by (simp add: bit_eq_iff) (auto simp add: bit_mask_iff bit_ucast_iff exp_eq_zero_iff) |
2355 by (simp add: bit_eq_iff) (auto simp add: bit_mask_iff bit_ucast_iff) |
2362 |
2356 |
2363 \<comment> \<open>literal u(s)cast\<close> |
2357 \<comment> \<open>literal u(s)cast\<close> |
2364 lemma ucast_bintr [simp]: |
2358 lemma ucast_bintr [simp]: |
2365 "ucast (numeral w :: 'a::len word) = |
2359 "ucast (numeral w :: 'a::len word) = |
2366 word_of_int (take_bit (LENGTH('a)) (numeral w))" |
2360 word_of_int (take_bit (LENGTH('a)) (numeral w))" |
3621 |
3615 |
3622 subsubsection \<open>Mask\<close> |
3616 subsubsection \<open>Mask\<close> |
3623 |
3617 |
3624 lemma minus_1_eq_mask: |
3618 lemma minus_1_eq_mask: |
3625 \<open>- 1 = (mask LENGTH('a) :: 'a::len word)\<close> |
3619 \<open>- 1 = (mask LENGTH('a) :: 'a::len word)\<close> |
3626 by (rule bit_eqI) (simp add: bit_exp_iff bit_mask_iff exp_eq_zero_iff) |
3620 by (rule bit_eqI) (simp add: bit_exp_iff bit_mask_iff) |
3627 |
3621 |
3628 lemma mask_eq_decr_exp: |
3622 lemma mask_eq_decr_exp: |
3629 \<open>mask n = 2 ^ n - (1 :: 'a::len word)\<close> |
3623 \<open>mask n = 2 ^ n - (1 :: 'a::len word)\<close> |
3630 by (fact mask_eq_exp_minus_1) |
3624 by (fact mask_eq_exp_minus_1) |
3631 |
3625 |
3636 context |
3630 context |
3637 begin |
3631 begin |
3638 |
3632 |
3639 qualified lemma bit_mask_iff [bit_simps]: |
3633 qualified lemma bit_mask_iff [bit_simps]: |
3640 \<open>bit (mask m :: 'a::len word) n \<longleftrightarrow> n < min LENGTH('a) m\<close> |
3634 \<open>bit (mask m :: 'a::len word) n \<longleftrightarrow> n < min LENGTH('a) m\<close> |
3641 by (simp add: bit_mask_iff exp_eq_zero_iff not_le) |
3635 by (simp add: bit_mask_iff not_le) |
3642 |
3636 |
3643 end |
3637 end |
3644 |
3638 |
3645 lemma mask_bin: "mask n = word_of_int (take_bit n (- 1))" |
3639 lemma mask_bin: "mask n = word_of_int (take_bit n (- 1))" |
3646 by transfer (simp add: take_bit_minus_one_eq_mask) |
3640 by transfer (simp add: take_bit_minus_one_eq_mask) |
4216 |
4210 |
4217 lemma word_rec_Pred: "n \<noteq> 0 \<Longrightarrow> word_rec z s n = s (n - 1) (word_rec z s (n - 1))" |
4211 lemma word_rec_Pred: "n \<noteq> 0 \<Longrightarrow> word_rec z s n = s (n - 1) (word_rec z s (n - 1))" |
4218 by (metis add.commute diff_add_cancel word_rec_Suc) |
4212 by (metis add.commute diff_add_cancel word_rec_Suc) |
4219 |
4213 |
4220 lemma word_rec_in: "f (word_rec z (\<lambda>_. f) n) = word_rec (f z) (\<lambda>_. f) n" |
4214 lemma word_rec_in: "f (word_rec z (\<lambda>_. f) n) = word_rec (f z) (\<lambda>_. f) n" |
4221 by (induct n) (simp_all add: word_rec_Suc) |
4215 by (induct n) simp_all |
4222 |
4216 |
4223 lemma word_rec_in2: "f n (word_rec z f n) = word_rec (f 0 z) (f \<circ> (+) 1) n" |
4217 lemma word_rec_in2: "f n (word_rec z f n) = word_rec (f 0 z) (f \<circ> (+) 1) n" |
4224 by (induct n) (simp_all add: word_rec_Suc) |
4218 by (induct n) simp_all |
4225 |
4219 |
4226 lemma word_rec_twice: |
4220 lemma word_rec_twice: |
4227 "m \<le> n \<Longrightarrow> word_rec z f n = word_rec (word_rec z f (n - m)) (f \<circ> (+) (n - m)) m" |
4221 "m \<le> n \<Longrightarrow> word_rec z f n = word_rec (word_rec z f (n - m)) (f \<circ> (+) (n - m)) m" |
4228 proof (induction n arbitrary: z f) |
4222 proof (induction n arbitrary: z f) |
4229 case zero |
4223 case zero |