293 \<open>signed 0 = 0\<close> |
292 \<open>signed 0 = 0\<close> |
294 by transfer simp |
293 by transfer simp |
295 |
294 |
296 lemma signed_1 [simp]: |
295 lemma signed_1 [simp]: |
297 \<open>signed (1 :: 'b::len word) = (if LENGTH('b) = 1 then - 1 else 1)\<close> |
296 \<open>signed (1 :: 'b::len word) = (if LENGTH('b) = 1 then - 1 else 1)\<close> |
298 by (transfer fixing: uminus; cases \<open>LENGTH('b)\<close>) |
297 by (transfer fixing: uminus; cases \<open>LENGTH('b)\<close>) (auto dest: gr0_implies_Suc) |
299 (simp_all add: sbintrunc_minus_simps) |
|
300 |
298 |
301 lemma signed_minus_1 [simp]: |
299 lemma signed_minus_1 [simp]: |
302 \<open>signed (- 1 :: 'b::len word) = - 1\<close> |
300 \<open>signed (- 1 :: 'b::len word) = - 1\<close> |
303 by (transfer fixing: uminus) simp |
301 by (transfer fixing: uminus) simp |
304 |
302 |
1656 lemma word_zero_le [simp]: "0 \<le> y" |
1654 lemma word_zero_le [simp]: "0 \<le> y" |
1657 for y :: "'a::len word" |
1655 for y :: "'a::len word" |
1658 by (fact word_coorder.extremum) |
1656 by (fact word_coorder.extremum) |
1659 |
1657 |
1660 lemma word_m1_ge [simp] : "word_pred 0 \<ge> y" (* FIXME: delete *) |
1658 lemma word_m1_ge [simp] : "word_pred 0 \<ge> y" (* FIXME: delete *) |
1661 by transfer (simp add: take_bit_minus_one_eq_mask mask_eq_exp_minus_1 bintr_lt2p) |
1659 by transfer (simp add: take_bit_minus_one_eq_mask mask_eq_exp_minus_1 ) |
1662 |
1660 |
1663 lemma word_n1_ge [simp]: "y \<le> -1" |
1661 lemma word_n1_ge [simp]: "y \<le> -1" |
1664 for y :: "'a::len word" |
1662 for y :: "'a::len word" |
1665 by (fact word_order.extremum) |
1663 by (fact word_order.extremum) |
1666 |
1664 |
1764 for w :: \<open>'a::len word\<close> |
1762 for w :: \<open>'a::len word\<close> |
1765 by (simp add: shiftl1_eq_mult_2 bit_double_iff exp_eq_zero_iff not_le) (simp add: ac_simps) |
1763 by (simp add: shiftl1_eq_mult_2 bit_double_iff exp_eq_zero_iff not_le) (simp add: ac_simps) |
1766 |
1764 |
1767 lift_definition shiftr1 :: \<open>'a::len word \<Rightarrow> 'a word\<close> |
1765 lift_definition shiftr1 :: \<open>'a::len word \<Rightarrow> 'a word\<close> |
1768 \<comment> \<open>shift right as unsigned or as signed, ie logical or arithmetic\<close> |
1766 \<comment> \<open>shift right as unsigned or as signed, ie logical or arithmetic\<close> |
1769 is \<open>\<lambda>k. take_bit LENGTH('a) k div 2\<close> by simp |
1767 is \<open>\<lambda>k. take_bit LENGTH('a) k div 2\<close> |
|
1768 by simp |
1770 |
1769 |
1771 lemma shiftr1_eq_div_2: |
1770 lemma shiftr1_eq_div_2: |
1772 \<open>shiftr1 w = w div 2\<close> |
1771 \<open>shiftr1 w = w div 2\<close> |
1773 by transfer simp |
1772 by transfer simp |
1774 |
1773 |
1882 qed |
1881 qed |
1883 |
1882 |
1884 lemma shiftr_def: |
1883 lemma shiftr_def: |
1885 \<open>w >> n = (shiftr1 ^^ n) w\<close> |
1884 \<open>w >> n = (shiftr1 ^^ n) w\<close> |
1886 proof - |
1885 proof - |
1887 have \<open>drop_bit n = (((\<lambda>k::int. k div 2) ^^ n))\<close> for n |
1886 have \<open>shiftr1 ^^ n = (drop_bit n :: 'a word \<Rightarrow> 'a word)\<close> |
1888 by (rule sym, induction n) |
1887 apply (induction n) |
1889 (simp_all add: fun_eq_iff drop_bit_Suc flip: drop_bit_half) |
1888 apply simp |
|
1889 apply (simp only: shiftr1_eq_div_2 [abs_def] drop_bit_eq_div [abs_def] funpow_Suc_right) |
|
1890 apply (use div_exp_eq [of _ 1, where ?'a = \<open>'a word\<close>] in simp) |
|
1891 done |
1890 then show ?thesis |
1892 then show ?thesis |
1891 apply transfer |
1893 by (simp add: shiftr_word_eq) |
1892 apply simp |
|
1893 apply (metis bintrunc_bintrunc rco_bintr) |
|
1894 done |
|
1895 qed |
1894 qed |
1896 |
1895 |
1897 lemma bit_shiftl_word_iff: |
1896 lemma bit_shiftl_word_iff: |
1898 \<open>bit (w << m) n \<longleftrightarrow> m \<le> n \<and> n < LENGTH('a) \<and> bit w (n - m)\<close> |
1897 \<open>bit (w << m) n \<longleftrightarrow> m \<le> n \<and> n < LENGTH('a) \<and> bit w (n - m)\<close> |
1899 for w :: \<open>'a::len word\<close> |
1898 for w :: \<open>'a::len word\<close> |
2027 apply (auto simp add: bit_drop_bit_eq bit_signed_take_bit_iff not_le min_def) |
2026 apply (auto simp add: bit_drop_bit_eq bit_signed_take_bit_iff not_le min_def) |
2028 apply (metis add.commute le_antisym less_diff_conv less_eq_decr_length_iff) |
2027 apply (metis add.commute le_antisym less_diff_conv less_eq_decr_length_iff) |
2029 apply (metis le_antisym less_eq_decr_length_iff) |
2028 apply (metis le_antisym less_eq_decr_length_iff) |
2030 done |
2029 done |
2031 |
2030 |
|
2031 lemma signed_drop_bit_signed_drop_bit [simp]: |
|
2032 \<open>signed_drop_bit m (signed_drop_bit n w) = signed_drop_bit (m + n) w\<close> |
|
2033 for w :: \<open>'a::len word\<close> |
|
2034 apply (cases \<open>LENGTH('a)\<close>) |
|
2035 apply simp_all |
|
2036 apply (rule bit_word_eqI) |
|
2037 apply (auto simp add: bit_signed_drop_bit_iff not_le less_diff_conv ac_simps) |
|
2038 done |
|
2039 |
2032 lemma signed_drop_bit_0 [simp]: |
2040 lemma signed_drop_bit_0 [simp]: |
2033 \<open>signed_drop_bit 0 w = w\<close> |
2041 \<open>signed_drop_bit 0 w = w\<close> |
2034 by transfer simp |
2042 by transfer (simp add: take_bit_signed_take_bit) |
2035 |
2043 |
2036 lemma sint_signed_drop_bit_eq: |
2044 lemma sint_signed_drop_bit_eq: |
2037 \<open>sint (signed_drop_bit n w) = drop_bit n (sint w)\<close> |
2045 \<open>sint (signed_drop_bit n w) = drop_bit n (sint w)\<close> |
2038 apply (cases \<open>LENGTH('a)\<close>; cases n) |
2046 apply (cases \<open>LENGTH('a)\<close>; cases n) |
2039 apply simp_all |
2047 apply simp_all |
2040 apply (rule bit_eqI) |
2048 apply (rule bit_eqI) |
2041 apply (auto simp add: bit_sint_iff bit_drop_bit_eq bit_signed_drop_bit_iff dest: bit_imp_le_length) |
2049 apply (auto simp add: bit_sint_iff bit_drop_bit_eq bit_signed_drop_bit_iff dest: bit_imp_le_length) |
2042 done |
2050 done |
2043 |
2051 |
|
2052 lift_definition sshiftr :: \<open>'a::len word \<Rightarrow> nat \<Rightarrow> 'a word\<close> (infixl \<open>>>>\<close> 55) |
|
2053 is \<open>\<lambda>k n. take_bit LENGTH('a) (drop_bit n (signed_take_bit (LENGTH('a) - Suc 0) k))\<close> |
|
2054 by (simp flip: signed_take_bit_decr_length_iff) |
|
2055 |
2044 lift_definition sshiftr1 :: \<open>'a::len word \<Rightarrow> 'a word\<close> |
2056 lift_definition sshiftr1 :: \<open>'a::len word \<Rightarrow> 'a word\<close> |
2045 is \<open>\<lambda>k. take_bit LENGTH('a) (signed_take_bit (LENGTH('a) - 1) k div 2)\<close> |
2057 is \<open>\<lambda>k. take_bit LENGTH('a) (signed_take_bit (LENGTH('a) - Suc 0) k div 2)\<close> |
2046 by (simp flip: signed_take_bit_decr_length_iff) |
|
2047 |
|
2048 lift_definition sshiftr :: \<open>'a::len word \<Rightarrow> nat \<Rightarrow> 'a word\<close> (infixl \<open>>>>\<close> 55) |
|
2049 is \<open>\<lambda>k n. take_bit LENGTH('a) (drop_bit n (signed_take_bit (LENGTH('a) - 1) k))\<close> |
|
2050 by (simp flip: signed_take_bit_decr_length_iff) |
2058 by (simp flip: signed_take_bit_decr_length_iff) |
2051 |
2059 |
2052 lift_definition bshiftr1 :: \<open>bool \<Rightarrow> 'a::len word \<Rightarrow> 'a word\<close> |
2060 lift_definition bshiftr1 :: \<open>bool \<Rightarrow> 'a::len word \<Rightarrow> 'a word\<close> |
2053 is \<open>\<lambda>b k. take_bit LENGTH('a) k div 2 + of_bool b * 2 ^ (LENGTH('a) - Suc 0)\<close> |
2061 is \<open>\<lambda>b k. take_bit LENGTH('a) k div 2 + of_bool b * 2 ^ (LENGTH('a) - Suc 0)\<close> |
2054 by (fact arg_cong) |
2062 by (fact arg_cong) |
2055 |
2063 |
|
2064 lemma sshiftr_eq: |
|
2065 \<open>w >>> n = signed_drop_bit n w\<close> |
|
2066 by transfer simp |
|
2067 |
|
2068 lemma sshiftr1_eq_signed_drop_bit_Suc_0: |
|
2069 \<open>sshiftr1 = signed_drop_bit (Suc 0)\<close> |
|
2070 by (rule ext) (transfer, simp add: drop_bit_Suc) |
|
2071 |
2056 lemma sshiftr1_eq: |
2072 lemma sshiftr1_eq: |
2057 \<open>sshiftr1 w = word_of_int (sint w div 2)\<close> |
2073 \<open>sshiftr1 w = word_of_int (sint w div 2)\<close> |
2058 by transfer simp |
2074 by transfer simp |
2059 |
2075 |
2060 lemma sshiftr_eq_funpow_sshiftr1: |
2076 lemma sshiftr_eq_funpow_sshiftr1: |
2061 \<open>w >>> n = (sshiftr1 ^^ n) w\<close> |
2077 \<open>w >>> n = (sshiftr1 ^^ n) w\<close> |
2062 proof - |
2078 apply (rule sym) |
2063 have *: \<open>(\<lambda>k::int. take_bit LENGTH('a) (signed_take_bit (LENGTH('a) - Suc 0) k div 2)) ^^ Suc n = |
2079 apply (simp add: sshiftr1_eq_signed_drop_bit_Suc_0 sshiftr_eq) |
2064 take_bit LENGTH('a) \<circ> drop_bit (Suc n) \<circ> signed_take_bit (LENGTH('a) - Suc 0)\<close> |
2080 apply (induction n) |
2065 for n |
2081 apply simp_all |
2066 apply (induction n) |
2082 done |
2067 apply (auto simp add: fun_eq_iff drop_bit_Suc) |
|
2068 apply (metis (no_types, lifting) Suc_pred funpow_swap1 len_gt_0 sbintrunc_bintrunc sbintrunc_rest) |
|
2069 done |
|
2070 show ?thesis |
|
2071 apply transfer |
|
2072 apply simp |
|
2073 subgoal for k n |
|
2074 apply (cases n) |
|
2075 apply (simp_all only: *) |
|
2076 apply simp_all |
|
2077 done |
|
2078 done |
|
2079 qed |
|
2080 |
2083 |
2081 lemma mask_eq: |
2084 lemma mask_eq: |
2082 \<open>mask n = (1 << n) - (1 :: 'a::len word)\<close> |
2085 \<open>mask n = (1 << n) - (1 :: 'a::len word)\<close> |
2083 by transfer (simp add: mask_eq_exp_minus_1 push_bit_of_1) |
2086 by transfer (simp add: mask_eq_exp_minus_1 push_bit_of_1) |
2084 |
2087 |
2258 by transfer (simp add: concat_bit_eq ac_simps) |
2261 by transfer (simp add: concat_bit_eq ac_simps) |
2259 |
2262 |
2260 lemma word_cat_eq' [code]: |
2263 lemma word_cat_eq' [code]: |
2261 \<open>word_cat a b = word_of_int (concat_bit LENGTH('b) (uint b) (uint a))\<close> |
2264 \<open>word_cat a b = word_of_int (concat_bit LENGTH('b) (uint b) (uint a))\<close> |
2262 for a :: \<open>'a::len word\<close> and b :: \<open>'b::len word\<close> |
2265 for a :: \<open>'a::len word\<close> and b :: \<open>'b::len word\<close> |
2263 by transfer simp |
2266 by transfer (simp add: concat_bit_take_bit_eq) |
2264 |
2267 |
2265 lemma bit_word_cat_iff: |
2268 lemma bit_word_cat_iff: |
2266 \<open>bit (word_cat v w :: 'c::len word) n \<longleftrightarrow> n < LENGTH('c) \<and> (if n < LENGTH('b) then bit w n else bit v (n - LENGTH('b)))\<close> |
2269 \<open>bit (word_cat v w :: 'c::len word) n \<longleftrightarrow> n < LENGTH('c) \<and> (if n < LENGTH('b) then bit w n else bit v (n - LENGTH('b)))\<close> |
2267 for v :: \<open>'a::len word\<close> and w :: \<open>'b::len word\<close> |
2270 for v :: \<open>'a::len word\<close> and w :: \<open>'b::len word\<close> |
2268 by transfer (simp add: bit_concat_bit_iff bit_take_bit_iff) |
2271 by transfer (simp add: bit_concat_bit_iff bit_take_bit_iff) |
2269 |
2272 |
2270 definition word_split :: "'a::len word \<Rightarrow> 'b::len word \<times> 'c::len word" |
2273 definition word_split :: \<open>'a::len word \<Rightarrow> 'b::len word \<times> 'c::len word\<close> |
2271 where "word_split a = |
2274 where \<open>word_split w = |
2272 (case bin_split (LENGTH('c)) (uint a) of |
2275 (ucast (drop_bit LENGTH('c) w) :: 'b::len word, ucast w :: 'c::len word)\<close> |
2273 (u, v) \<Rightarrow> (word_of_int u, word_of_int v))" |
|
2274 |
2276 |
2275 definition word_rcat :: \<open>'a::len word list \<Rightarrow> 'b::len word\<close> |
2277 definition word_rcat :: \<open>'a::len word list \<Rightarrow> 'b::len word\<close> |
2276 where \<open>word_rcat = word_of_int \<circ> horner_sum uint (2 ^ LENGTH('a)) \<circ> rev\<close> |
2278 where \<open>word_rcat = word_of_int \<circ> horner_sum uint (2 ^ LENGTH('a)) \<circ> rev\<close> |
2277 |
|
2278 lemma word_rcat_eq: |
|
2279 \<open>word_rcat ws = word_of_int (bin_rcat (LENGTH('a::len)) (map uint ws))\<close> |
|
2280 for ws :: \<open>'a::len word list\<close> |
|
2281 apply (simp add: word_rcat_def bin_rcat_def rev_map) |
|
2282 apply transfer |
|
2283 apply (simp add: horner_sum_foldr foldr_map comp_def) |
|
2284 done |
|
2285 |
2279 |
2286 abbreviation (input) max_word :: \<open>'a::len word\<close> |
2280 abbreviation (input) max_word :: \<open>'a::len word\<close> |
2287 \<comment> \<open>Largest representable machine integer.\<close> |
2281 \<comment> \<open>Largest representable machine integer.\<close> |
2288 where "max_word \<equiv> - 1" |
2282 where "max_word \<equiv> - 1" |
2289 |
2283 |
2290 |
2284 |
2291 subsection \<open>More on conversions\<close> |
2285 subsection \<open>More on conversions\<close> |
2292 |
2286 |
2293 lemma int_word_sint: |
2287 lemma int_word_sint: |
2294 \<open>sint (word_of_int x :: 'a::len word) = (x + 2 ^ (LENGTH('a) - 1)) mod 2 ^ LENGTH('a) - 2 ^ (LENGTH('a) - 1)\<close> |
2288 \<open>sint (word_of_int x :: 'a::len word) = (x + 2 ^ (LENGTH('a) - 1)) mod 2 ^ LENGTH('a) - 2 ^ (LENGTH('a) - 1)\<close> |
2295 by transfer (simp add: no_sbintr_alt2) |
2289 by transfer (simp flip: take_bit_eq_mod add: signed_take_bit_eq_take_bit_shift) |
2296 |
2290 |
2297 lemma sint_sbintrunc': "sint (word_of_int bin :: 'a word) = signed_take_bit (LENGTH('a::len) - 1) bin" |
2291 lemma sint_sbintrunc': "sint (word_of_int bin :: 'a word) = signed_take_bit (LENGTH('a::len) - 1) bin" |
2298 by simp |
2292 by simp |
2299 |
2293 |
2300 lemma uint_sint: "uint w = take_bit (LENGTH('a)) (sint w)" |
2294 lemma uint_sint: "uint w = take_bit LENGTH('a) (sint w)" |
2301 for w :: "'a::len word" |
2295 for w :: "'a::len word" |
2302 by transfer simp |
2296 by transfer (simp add: take_bit_signed_take_bit) |
2303 |
2297 |
2304 lemma bintr_uint: "LENGTH('a) \<le> n \<Longrightarrow> take_bit n (uint w) = uint w" |
2298 lemma bintr_uint: "LENGTH('a) \<le> n \<Longrightarrow> take_bit n (uint w) = uint w" |
2305 for w :: "'a::len word" |
2299 for w :: "'a::len word" |
2306 by transfer (simp add: min_def) |
2300 by transfer (simp add: min_def) |
2307 |
2301 |
2362 |
2356 |
2363 lemma sint_lt: "sint x < 2 ^ (LENGTH('a) - 1)" |
2357 lemma sint_lt: "sint x < 2 ^ (LENGTH('a) - 1)" |
2364 for x :: "'a::len word" |
2358 for x :: "'a::len word" |
2365 using sint_less [of x] by simp |
2359 using sint_less [of x] by simp |
2366 |
2360 |
2367 lemma sign_uint_Pls [simp]: "bin_sign (uint x) = 0" |
|
2368 by (simp add: sign_Pls_ge_0) |
|
2369 |
|
2370 lemma uint_m2p_neg: "uint x - 2 ^ LENGTH('a) < 0" |
2361 lemma uint_m2p_neg: "uint x - 2 ^ LENGTH('a) < 0" |
2371 for x :: "'a::len word" |
2362 for x :: "'a::len word" |
2372 by (simp only: diff_less_0_iff_less uint_lt2p) |
2363 by (simp only: diff_less_0_iff_less uint_lt2p) |
2373 |
2364 |
2374 lemma uint_m2p_not_non_neg: "\<not> 0 \<le> uint x - 2 ^ LENGTH('a)" |
2365 lemma uint_m2p_not_non_neg: "\<not> 0 \<le> uint x - 2 ^ LENGTH('a)" |
2375 for x :: "'a::len word" |
2366 for x :: "'a::len word" |
2376 by (simp only: not_le uint_m2p_neg) |
2367 by (simp only: not_le uint_m2p_neg) |
2377 |
2368 |
2378 lemma lt2p_lem: "LENGTH('a) \<le> n \<Longrightarrow> uint w < 2 ^ n" |
2369 lemma lt2p_lem: "LENGTH('a) \<le> n \<Longrightarrow> uint w < 2 ^ n" |
2379 for w :: "'a::len word" |
2370 for w :: "'a::len word" |
2380 by (metis bintr_lt2p bintr_uint) |
2371 using uint_bounded [of w] by (rule less_le_trans) simp |
2381 |
2372 |
2382 lemma uint_le_0_iff [simp]: "uint x \<le> 0 \<longleftrightarrow> uint x = 0" |
2373 lemma uint_le_0_iff [simp]: "uint x \<le> 0 \<longleftrightarrow> uint x = 0" |
2383 by (fact uint_ge_0 [THEN leD, THEN antisym_conv1]) |
2374 by (fact uint_ge_0 [THEN leD, THEN antisym_conv1]) |
2384 |
2375 |
2385 lemma uint_nat: "uint w = int (unat w)" |
2376 lemma uint_nat: "uint w = int (unat w)" |
2467 |
2458 |
2468 lemma word_eqD: "u = v \<Longrightarrow> u !! x = v !! x" |
2459 lemma word_eqD: "u = v \<Longrightarrow> u !! x = v !! x" |
2469 for u v :: "'a::len word" |
2460 for u v :: "'a::len word" |
2470 by simp |
2461 by simp |
2471 |
2462 |
2472 lemma test_bit_bin': "w !! n \<longleftrightarrow> n < size w \<and> bin_nth (uint w) n" |
2463 lemma test_bit_bin': "w !! n \<longleftrightarrow> n < size w \<and> bit (uint w) n" |
2473 by transfer (simp add: bit_take_bit_iff) |
2464 by transfer (simp add: bit_take_bit_iff) |
2474 |
2465 |
2475 lemmas test_bit_bin = test_bit_bin' [unfolded word_size] |
2466 lemmas test_bit_bin = test_bit_bin' [unfolded word_size] |
2476 |
2467 |
2477 lemma bin_nth_uint_imp: "bin_nth (uint w) n \<Longrightarrow> n < LENGTH('a)" |
2468 lemma bin_nth_uint_imp: "bit (uint w) n \<Longrightarrow> n < LENGTH('a)" |
2478 for w :: "'a::len word" |
2469 for w :: "'a::len word" |
2479 by transfer (simp add: bit_take_bit_iff) |
2470 by transfer (simp add: bit_take_bit_iff) |
2480 |
2471 |
2481 lemma bin_nth_sint: |
2472 lemma bin_nth_sint: |
2482 "LENGTH('a) \<le> n \<Longrightarrow> |
2473 "LENGTH('a) \<le> n \<Longrightarrow> |
2483 bin_nth (sint w) n = bin_nth (sint w) (LENGTH('a) - 1)" |
2474 bit (sint w) n = bit (sint w) (LENGTH('a) - 1)" |
2484 for w :: "'a::len word" |
2475 for w :: "'a::len word" |
2485 by (transfer fixing: n) (simp add: bit_signed_take_bit_iff le_diff_conv min_def) |
2476 by (transfer fixing: n) (simp add: bit_signed_take_bit_iff le_diff_conv min_def) |
2486 |
2477 |
2487 lemma num_of_bintr': |
2478 lemma num_of_bintr': |
2488 "take_bit (LENGTH('a::len)) (numeral a :: int) = (numeral b) \<Longrightarrow> |
2479 "take_bit (LENGTH('a::len)) (numeral a :: int) = (numeral b) \<Longrightarrow> |
2501 proof (transfer fixing: a b) |
2492 proof (transfer fixing: a b) |
2502 assume \<open>signed_take_bit (LENGTH('a) - 1) (numeral a :: int) = numeral b\<close> |
2493 assume \<open>signed_take_bit (LENGTH('a) - 1) (numeral a :: int) = numeral b\<close> |
2503 then have \<open>take_bit LENGTH('a) (signed_take_bit (LENGTH('a) - 1) (numeral a :: int)) = take_bit LENGTH('a) (numeral b)\<close> |
2494 then have \<open>take_bit LENGTH('a) (signed_take_bit (LENGTH('a) - 1) (numeral a :: int)) = take_bit LENGTH('a) (numeral b)\<close> |
2504 by simp |
2495 by simp |
2505 then show \<open>take_bit LENGTH('a) (numeral a :: int) = take_bit LENGTH('a) (numeral b)\<close> |
2496 then show \<open>take_bit LENGTH('a) (numeral a :: int) = take_bit LENGTH('a) (numeral b)\<close> |
2506 by simp |
2497 by (simp add: take_bit_signed_take_bit) |
2507 qed |
2498 qed |
2508 |
2499 |
2509 lemma num_abs_bintr: |
2500 lemma num_abs_bintr: |
2510 "(numeral x :: 'a word) = |
2501 "(numeral x :: 'a word) = |
2511 word_of_int (take_bit (LENGTH('a::len)) (numeral x))" |
2502 word_of_int (take_bit (LENGTH('a::len)) (numeral x))" |
2512 by transfer simp |
2503 by transfer simp |
2513 |
2504 |
2514 lemma num_abs_sbintr: |
2505 lemma num_abs_sbintr: |
2515 "(numeral x :: 'a word) = |
2506 "(numeral x :: 'a word) = |
2516 word_of_int (signed_take_bit (LENGTH('a::len) - 1) (numeral x))" |
2507 word_of_int (signed_take_bit (LENGTH('a::len) - 1) (numeral x))" |
2517 by transfer simp |
2508 by transfer (simp add: take_bit_signed_take_bit) |
2518 |
2509 |
2519 text \<open> |
2510 text \<open> |
2520 \<open>cast\<close> -- note, no arg for new length, as it's determined by type of result, |
2511 \<open>cast\<close> -- note, no arg for new length, as it's determined by type of result, |
2521 thus in \<open>cast w = w\<close>, the type means cast to length of \<open>w\<close>! |
2512 thus in \<open>cast w = w\<close>, the type means cast to length of \<open>w\<close>! |
2522 \<close> |
2513 \<close> |
2741 and "sint (- a) = signed_take_bit (LENGTH('a) - 1) (- sint a)" |
2732 and "sint (- a) = signed_take_bit (LENGTH('a) - 1) (- sint a)" |
2742 and "sint (word_succ a) = signed_take_bit (LENGTH('a) - 1) (sint a + 1)" |
2733 and "sint (word_succ a) = signed_take_bit (LENGTH('a) - 1) (sint a + 1)" |
2743 and "sint (word_pred a) = signed_take_bit (LENGTH('a) - 1) (sint a - 1)" |
2734 and "sint (word_pred a) = signed_take_bit (LENGTH('a) - 1) (sint a - 1)" |
2744 and "sint (0 :: 'a word) = signed_take_bit (LENGTH('a) - 1) 0" |
2735 and "sint (0 :: 'a word) = signed_take_bit (LENGTH('a) - 1) 0" |
2745 and "sint (1 :: 'a word) = signed_take_bit (LENGTH('a) - 1) 1" |
2736 and "sint (1 :: 'a word) = signed_take_bit (LENGTH('a) - 1) 1" |
2746 prefer 8 |
2737 apply transfer apply (simp add: signed_take_bit_add) |
2747 apply (simp add: Suc_lessI sbintrunc_minus_simps(3)) |
2738 apply transfer apply (simp add: signed_take_bit_diff) |
2748 prefer 7 |
2739 apply transfer apply (simp add: signed_take_bit_mult) |
2749 apply simp |
2740 apply transfer apply (simp add: signed_take_bit_minus) |
2750 apply transfer apply (simp add: signed_take_bit_add) |
2741 apply (metis of_int_sint scast_id sint_sbintrunc' wi_hom_succ) |
2751 apply transfer apply (simp add: signed_take_bit_diff) |
2742 apply (metis of_int_sint scast_id sint_sbintrunc' wi_hom_pred) |
2752 apply transfer apply (simp add: signed_take_bit_mult) |
2743 apply (simp_all add: sint_uint) |
2753 apply transfer apply (simp add: signed_take_bit_minus) |
|
2754 apply (metis One_nat_def id_apply of_int_eq_id sbintrunc_sbintrunc signed.rep_eq signed_word_eqI sint_sbintrunc' wi_hom_succ) |
|
2755 apply (metis (no_types, lifting) One_nat_def signed_take_bit_decr_length_iff sint_uint uint_sint uint_word_of_int_eq wi_hom_pred word_of_int_uint) |
|
2756 done |
2744 done |
2757 |
2745 |
2758 lemma word_pred_0_n1: "word_pred 0 = word_of_int (- 1)" |
2746 lemma word_pred_0_n1: "word_pred 0 = word_of_int (- 1)" |
2759 unfolding word_pred_m1 by simp |
2747 unfolding word_pred_m1 by simp |
2760 |
2748 |
2935 |
2923 |
2936 lemma uint_add_le: "uint (x + y) \<le> uint x + uint y" |
2924 lemma uint_add_le: "uint (x + y) \<le> uint x + uint y" |
2937 unfolding uint_word_ariths by (simp add: zmod_le_nonneg_dividend) |
2925 unfolding uint_word_ariths by (simp add: zmod_le_nonneg_dividend) |
2938 |
2926 |
2939 lemma uint_sub_ge: "uint (x - y) \<ge> uint x - uint y" |
2927 lemma uint_sub_ge: "uint (x - y) \<ge> uint x - uint y" |
2940 unfolding uint_word_ariths by (simp add: int_mod_ge) |
2928 unfolding uint_word_ariths |
2941 |
2929 by (simp flip: take_bit_eq_mod add: take_bit_int_greater_eq_self_iff) |
|
2930 |
|
2931 lemma int_mod_ge: \<open>a \<le> a mod n\<close> if \<open>a < n\<close> \<open>0 < n\<close> |
|
2932 for a n :: int |
|
2933 proof (cases \<open>a < 0\<close>) |
|
2934 case True |
|
2935 with \<open>0 < n\<close> show ?thesis |
|
2936 by (metis less_trans not_less pos_mod_conj) |
|
2937 |
|
2938 next |
|
2939 case False |
|
2940 with \<open>a < n\<close> show ?thesis |
|
2941 by simp |
|
2942 qed |
|
2943 |
2942 lemma mod_add_if_z: |
2944 lemma mod_add_if_z: |
2943 "x < z \<Longrightarrow> y < z \<Longrightarrow> 0 \<le> y \<Longrightarrow> 0 \<le> x \<Longrightarrow> 0 \<le> z \<Longrightarrow> |
2945 "x < z \<Longrightarrow> y < z \<Longrightarrow> 0 \<le> y \<Longrightarrow> 0 \<le> x \<Longrightarrow> 0 \<le> z \<Longrightarrow> |
2944 (x + y) mod z = (if x + y < z then x + y else x + y - z)" |
2946 (x + y) mod z = (if x + y < z then x + y else x + y - z)" |
2945 for x y z :: int |
2947 for x y z :: int |
2946 apply (auto simp add: not_less) |
2948 apply (auto simp add: not_less) |
2947 apply (rule antisym) |
2949 apply (rule antisym) |
2948 apply (metis diff_ge_0_iff_ge minus_mod_self2 zmod_le_nonneg_dividend) |
2950 apply (metis diff_ge_0_iff_ge minus_mod_self2 zmod_le_nonneg_dividend) |
2949 apply (simp only: flip: minus_mod_self2 [of \<open>x + y\<close> z]) |
2951 apply (simp only: flip: minus_mod_self2 [of \<open>x + y\<close> z]) |
2950 apply (rule int_mod_ge) |
2952 apply (metis add.commute add_less_cancel_left add_mono_thms_linordered_field(5) diff_add_cancel diff_ge_0_iff_ge mod_pos_pos_trivial order_refl) |
2951 apply simp_all |
|
2952 done |
2953 done |
2953 |
2954 |
2954 lemma uint_plus_if': |
2955 lemma uint_plus_if': |
2955 "uint (a + b) = |
2956 "uint (a + b) = |
2956 (if uint a + uint b < 2 ^ LENGTH('a) then uint a + uint b |
2957 (if uint a + uint b < 2 ^ LENGTH('a) then uint a + uint b |
3591 |
3592 |
3592 lemma inj_uint: \<open>inj uint\<close> |
3593 lemma inj_uint: \<open>inj uint\<close> |
3593 by (fact inj_unsigned) |
3594 by (fact inj_unsigned) |
3594 |
3595 |
3595 lemma range_uint: \<open>range (uint :: 'a word \<Rightarrow> int) = {0..<2 ^ LENGTH('a::len)}\<close> |
3596 lemma range_uint: \<open>range (uint :: 'a word \<Rightarrow> int) = {0..<2 ^ LENGTH('a::len)}\<close> |
3596 by transfer (auto simp add: bintr_lt2p range_bintrunc) |
3597 apply transfer |
|
3598 apply (auto simp add: image_iff) |
|
3599 apply (metis take_bit_int_eq_self_iff) |
|
3600 done |
3597 |
3601 |
3598 lemma UNIV_eq: \<open>(UNIV :: 'a word set) = word_of_int ` {0..<2 ^ LENGTH('a::len)}\<close> |
3602 lemma UNIV_eq: \<open>(UNIV :: 'a word set) = word_of_int ` {0..<2 ^ LENGTH('a::len)}\<close> |
3599 proof - |
3603 by (auto simp add: image_iff) (metis atLeastLessThan_iff linorder_not_le uint_split) |
3600 have \<open>uint ` (UNIV :: 'a word set) = uint ` (word_of_int :: int \<Rightarrow> 'a word) ` {0..<2 ^ LENGTH('a::len)}\<close> |
|
3601 by transfer (simp add: range_bintrunc, auto simp add: take_bit_eq_mod) |
|
3602 then show ?thesis |
|
3603 using inj_image_eq_iff [of \<open>uint :: 'a word \<Rightarrow> int\<close> \<open>UNIV :: 'a word set\<close> \<open>word_of_int ` {0..<2 ^ LENGTH('a)} :: 'a word set\<close>, OF inj_uint] |
|
3604 by simp |
|
3605 qed |
|
3606 |
3604 |
3607 lemma card_word: "CARD('a word) = 2 ^ LENGTH('a::len)" |
3605 lemma card_word: "CARD('a word) = 2 ^ LENGTH('a::len)" |
3608 by (simp add: UNIV_eq card_image inj_on_word_of_int) |
3606 by (simp add: UNIV_eq card_image inj_on_word_of_int) |
3609 |
3607 |
3610 lemma card_word_size: "CARD('a word) = 2 ^ size x" |
3608 lemma card_word_size: "CARD('a word) = 2 ^ size x" |
3614 instance word :: (len) finite |
3612 instance word :: (len) finite |
3615 by standard (simp add: UNIV_eq) |
3613 by standard (simp add: UNIV_eq) |
3616 |
3614 |
3617 |
3615 |
3618 subsection \<open>Bitwise Operations on Words\<close> |
3616 subsection \<open>Bitwise Operations on Words\<close> |
3619 |
|
3620 lemmas bin_log_bintrs = bin_trunc_not bin_trunc_xor bin_trunc_and bin_trunc_or |
|
3621 |
|
3622 \<comment> \<open>following definitions require both arithmetic and bit-wise word operations\<close> |
|
3623 |
|
3624 \<comment> \<open>to get \<open>word_no_log_defs\<close> from \<open>word_log_defs\<close>, using \<open>bin_log_bintrs\<close>\<close> |
|
3625 lemmas wils1 = bin_log_bintrs [THEN word_of_int_eq_iff [THEN iffD2], |
|
3626 folded uint_word_of_int_eq, THEN eq_reflection] |
|
3627 |
|
3628 \<comment> \<open>the binary operations only\<close> (* BH: why is this needed? *) |
|
3629 lemmas word_log_binary_defs = |
|
3630 word_and_def word_or_def word_xor_def |
|
3631 |
3617 |
3632 lemma word_wi_log_defs: |
3618 lemma word_wi_log_defs: |
3633 "NOT (word_of_int a) = word_of_int (NOT a)" |
3619 "NOT (word_of_int a) = word_of_int (NOT a)" |
3634 "word_of_int a AND word_of_int b = word_of_int (a AND b)" |
3620 "word_of_int a AND word_of_int b = word_of_int (a AND b)" |
3635 "word_of_int a OR word_of_int b = word_of_int (a OR b)" |
3621 "word_of_int a OR word_of_int b = word_of_int (a OR b)" |
3699 "(rel_fun pcr_word (rel_fun (=) (=))) |
3685 "(rel_fun pcr_word (rel_fun (=) (=))) |
3700 (\<lambda>x n. n < LENGTH('a) \<and> bit x n) (test_bit :: 'a::len word \<Rightarrow> _)" |
3686 (\<lambda>x n. n < LENGTH('a) \<and> bit x n) (test_bit :: 'a::len word \<Rightarrow> _)" |
3701 by (simp only: test_bit_eq_bit) transfer_prover |
3687 by (simp only: test_bit_eq_bit) transfer_prover |
3702 |
3688 |
3703 lemma test_bit_wi [simp]: |
3689 lemma test_bit_wi [simp]: |
3704 "(word_of_int x :: 'a::len word) !! n \<longleftrightarrow> n < LENGTH('a) \<and> bin_nth x n" |
3690 "(word_of_int x :: 'a::len word) !! n \<longleftrightarrow> n < LENGTH('a) \<and> bit x n" |
3705 by transfer simp |
3691 by transfer simp |
3706 |
3692 |
3707 lemma word_ops_nth_size: |
3693 lemma word_ops_nth_size: |
3708 "n < size x \<Longrightarrow> |
3694 "n < size x \<Longrightarrow> |
3709 (x OR y) !! n = (x !! n | y !! n) \<and> |
3695 (x OR y) !! n = (x !! n | y !! n) \<and> |
3710 (x AND y) !! n = (x !! n \<and> y !! n) \<and> |
3696 (x AND y) !! n = (x !! n \<and> y !! n) \<and> |
3711 (x XOR y) !! n = (x !! n \<noteq> y !! n) \<and> |
3697 (x XOR y) !! n = (x !! n \<noteq> y !! n) \<and> |
3712 (NOT x) !! n = (\<not> x !! n)" |
3698 (NOT x) !! n = (\<not> x !! n)" |
3713 for x :: "'a::len word" |
3699 for x :: "'a::len word" |
3714 unfolding word_size by transfer (simp add: bin_nth_ops) |
3700 by transfer (simp add: bit_or_iff bit_and_iff bit_xor_iff bit_not_iff) |
3715 |
3701 |
3716 lemma word_ao_nth: |
3702 lemma word_ao_nth: |
3717 "(x OR y) !! n = (x !! n | y !! n) \<and> |
3703 "(x OR y) !! n = (x !! n | y !! n) \<and> |
3718 (x AND y) !! n = (x !! n \<and> y !! n)" |
3704 (x AND y) !! n = (x !! n \<and> y !! n)" |
3719 for x :: "'a::len word" |
3705 for x :: "'a::len word" |
3720 by transfer (auto simp add: bin_nth_ops) |
3706 by transfer (auto simp add: bit_or_iff bit_and_iff) |
3721 |
3707 |
3722 lemmas msb0 = len_gt_0 [THEN diff_Suc_less, THEN word_ops_nth_size [unfolded word_size]] |
3708 lemmas msb0 = len_gt_0 [THEN diff_Suc_less, THEN word_ops_nth_size [unfolded word_size]] |
3723 lemmas msb1 = msb0 [where i = 0] |
3709 lemmas msb1 = msb0 [where i = 0] |
3724 |
3710 |
3725 lemma test_bit_numeral [simp]: |
3711 lemma test_bit_numeral [simp]: |
3726 "(numeral w :: 'a::len word) !! n \<longleftrightarrow> |
3712 "(numeral w :: 'a::len word) !! n \<longleftrightarrow> |
3727 n < LENGTH('a) \<and> bin_nth (numeral w) n" |
3713 n < LENGTH('a) \<and> bit (numeral w :: int) n" |
3728 by transfer (rule refl) |
3714 by transfer (rule refl) |
3729 |
3715 |
3730 lemma test_bit_neg_numeral [simp]: |
3716 lemma test_bit_neg_numeral [simp]: |
3731 "(- numeral w :: 'a::len word) !! n \<longleftrightarrow> |
3717 "(- numeral w :: 'a::len word) !! n \<longleftrightarrow> |
3732 n < LENGTH('a) \<and> bin_nth (- numeral w) n" |
3718 n < LENGTH('a) \<and> bit (- numeral w :: int) n" |
3733 by transfer (rule refl) |
3719 by transfer (rule refl) |
3734 |
3720 |
3735 lemma test_bit_1 [simp]: "(1 :: 'a::len word) !! n \<longleftrightarrow> n = 0" |
3721 lemma test_bit_1 [simp]: "(1 :: 'a::len word) !! n \<longleftrightarrow> n = 0" |
3736 by transfer auto |
3722 by transfer (auto simp add: bit_1_iff) |
3737 |
3723 |
3738 lemma nth_0 [simp]: "\<not> (0 :: 'a::len word) !! n" |
3724 lemma nth_0 [simp]: "\<not> (0 :: 'a::len word) !! n" |
3739 by transfer simp |
3725 by transfer simp |
3740 |
3726 |
3741 lemma nth_minus1 [simp]: "(-1 :: 'a::len word) !! n \<longleftrightarrow> n < LENGTH('a)" |
3727 lemma nth_minus1 [simp]: "(-1 :: 'a::len word) !! n \<longleftrightarrow> n < LENGTH('a)" |
3820 for x :: "'a::len word" |
3806 for x :: "'a::len word" |
3821 by (auto simp: word_eq_iff word_ops_nth_size [unfolded word_size]) |
3807 by (auto simp: word_eq_iff word_ops_nth_size [unfolded word_size]) |
3822 |
3808 |
3823 lemma word_add_not [simp]: "x + NOT x = -1" |
3809 lemma word_add_not [simp]: "x + NOT x = -1" |
3824 for x :: "'a::len word" |
3810 for x :: "'a::len word" |
3825 by transfer (simp add: bin_add_not) |
3811 by transfer (simp add: not_int_def) |
3826 |
3812 |
3827 lemma word_plus_and_or [simp]: "(x AND y) + (x OR y) = x + y" |
3813 lemma word_plus_and_or [simp]: "(x AND y) + (x OR y) = x + y" |
3828 for x :: "'a::len word" |
3814 for x :: "'a::len word" |
3829 by transfer (simp add: plus_and_or) |
3815 by transfer (simp add: plus_and_or) |
3830 |
3816 |
3840 for w w' :: "'a::len word" |
3826 for w w' :: "'a::len word" |
3841 by (auto intro: leoa leao) |
3827 by (auto intro: leoa leao) |
3842 |
3828 |
3843 lemma le_word_or2: "x \<le> x OR y" |
3829 lemma le_word_or2: "x \<le> x OR y" |
3844 for x y :: "'a::len word" |
3830 for x y :: "'a::len word" |
3845 by (auto simp: word_le_def uint_or intro: le_int_or) |
3831 by (simp add: or_greater_eq uint_or word_le_def) |
3846 |
3832 |
3847 lemmas le_word_or1 = xtrans(3) [OF word_bw_comms (2) le_word_or2] |
3833 lemmas le_word_or1 = xtrans(3) [OF word_bw_comms (2) le_word_or2] |
3848 lemmas word_and_le1 = xtrans(3) [OF word_ao_absorbs (4) [symmetric] le_word_or2] |
3834 lemmas word_and_le1 = xtrans(3) [OF word_ao_absorbs (4) [symmetric] le_word_or2] |
3849 lemmas word_and_le2 = xtrans(3) [OF word_ao_absorbs (8) [symmetric] le_word_or2] |
3835 lemmas word_and_le2 = xtrans(3) [OF word_ao_absorbs (8) [symmetric] le_word_or2] |
3850 |
3836 |
3875 lemmas lsb0 = len_gt_0 [THEN word_ops_nth_size [unfolded word_size]] |
3861 lemmas lsb0 = len_gt_0 [THEN word_ops_nth_size [unfolded word_size]] |
3876 |
3862 |
3877 lemma nth_sint: |
3863 lemma nth_sint: |
3878 fixes w :: "'a::len word" |
3864 fixes w :: "'a::len word" |
3879 defines "l \<equiv> LENGTH('a)" |
3865 defines "l \<equiv> LENGTH('a)" |
3880 shows "bin_nth (sint w) n = (if n < l - 1 then w !! n else w !! (l - 1))" |
3866 shows "bit (sint w) n = (if n < l - 1 then w !! n else w !! (l - 1))" |
3881 unfolding sint_uint l_def |
3867 unfolding sint_uint l_def |
3882 by (auto simp: nth_sbintr word_test_bit_def [symmetric]) |
3868 by (auto simp: bit_signed_take_bit_iff word_test_bit_def not_less min_def) |
3883 |
|
3884 lemma setBit_no [simp]: "setBit (numeral bin) n = word_of_int (bin_sc n True (numeral bin))" |
|
3885 by transfer (simp add: bin_sc_eq) |
|
3886 |
|
3887 lemma clearBit_no [simp]: |
|
3888 "clearBit (numeral bin) n = word_of_int (bin_sc n False (numeral bin))" |
|
3889 by transfer (simp add: bin_sc_eq) |
|
3890 |
3869 |
3891 lemma test_bit_2p: "(word_of_int (2 ^ n)::'a::len word) !! m \<longleftrightarrow> m = n \<and> m < LENGTH('a)" |
3870 lemma test_bit_2p: "(word_of_int (2 ^ n)::'a::len word) !! m \<longleftrightarrow> m = n \<and> m < LENGTH('a)" |
3892 by transfer (auto simp add: bit_exp_iff) |
3871 by transfer (auto simp add: bit_exp_iff) |
3893 |
3872 |
3894 lemma nth_w2p: "((2::'a::len word) ^ n) !! m \<longleftrightarrow> m = n \<and> m < LENGTH('a::len)" |
3873 lemma nth_w2p: "((2::'a::len word) ^ n) !! m \<longleftrightarrow> m = n \<and> m < LENGTH('a::len)" |
3971 apply (auto simp add: nth_shiftr1) |
3950 apply (auto simp add: nth_shiftr1) |
3972 done |
3951 done |
3973 |
3952 |
3974 text \<open> |
3953 text \<open> |
3975 see paper page 10, (1), (2), \<open>shiftr1_def\<close> is of the form of (1), |
3954 see paper page 10, (1), (2), \<open>shiftr1_def\<close> is of the form of (1), |
3976 where \<open>f\<close> (ie \<open>bin_rest\<close>) takes normal arguments to normal results, |
3955 where \<open>f\<close> (ie \<open>_ div 2\<close>) takes normal arguments to normal results, |
3977 thus we get (2) from (1) |
3956 thus we get (2) from (1) |
3978 \<close> |
3957 \<close> |
3979 |
3958 |
3980 lemma uint_shiftr1: "uint (shiftr1 w) = bin_rest (uint w)" |
3959 lemma uint_shiftr1: "uint (shiftr1 w) = uint w div 2" |
3981 by transfer simp |
3960 using uint_shiftr_eq [of w 1] |
|
3961 by (simp add: shiftr1_code) |
3982 |
3962 |
3983 lemma bit_sshiftr1_iff: |
3963 lemma bit_sshiftr1_iff: |
3984 \<open>bit (sshiftr1 w) n \<longleftrightarrow> bit w (if n = LENGTH('a) - 1 then LENGTH('a) - 1 else Suc n)\<close> |
3964 \<open>bit (sshiftr1 w) n \<longleftrightarrow> bit w (if n = LENGTH('a) - 1 then LENGTH('a) - 1 else Suc n)\<close> |
3985 for w :: \<open>'a::len word\<close> |
3965 for w :: \<open>'a::len word\<close> |
3986 apply transfer |
3966 apply transfer |
3996 apply (auto simp add: bit_take_bit_iff bit_drop_bit_eq bit_signed_take_bit_iff min_def not_le simp flip: bit_Suc) |
3976 apply (auto simp add: bit_take_bit_iff bit_drop_bit_eq bit_signed_take_bit_iff min_def not_le simp flip: bit_Suc) |
3997 using le_less_Suc_eq apply fastforce |
3977 using le_less_Suc_eq apply fastforce |
3998 using le_less_Suc_eq apply fastforce |
3978 using le_less_Suc_eq apply fastforce |
3999 done |
3979 done |
4000 |
3980 |
4001 lemma sshiftr_eq: |
|
4002 \<open>w >>> m = signed_drop_bit m w\<close> |
|
4003 by (rule bit_eqI) (simp add: bit_signed_drop_bit_iff bit_sshiftr_word_iff) |
|
4004 |
|
4005 lemma nth_sshiftr1: "sshiftr1 w !! n = (if n = size w - 1 then w !! n else w !! Suc n)" |
3981 lemma nth_sshiftr1: "sshiftr1 w !! n = (if n = size w - 1 then w !! n else w !! Suc n)" |
4006 apply transfer |
3982 apply transfer |
4007 apply (auto simp add: bit_take_bit_iff bit_signed_take_bit_iff min_def simp flip: bit_Suc) |
3983 apply (auto simp add: bit_take_bit_iff bit_signed_take_bit_iff min_def simp flip: bit_Suc) |
4008 using le_less_Suc_eq apply fastforce |
3984 using le_less_Suc_eq apply fastforce |
4009 using le_less_Suc_eq apply fastforce |
3985 using le_less_Suc_eq apply fastforce |
4020 |
3996 |
4021 lemma shiftr1_div_2: "uint (shiftr1 w) = uint w div 2" |
3997 lemma shiftr1_div_2: "uint (shiftr1 w) = uint w div 2" |
4022 by (fact uint_shiftr1) |
3998 by (fact uint_shiftr1) |
4023 |
3999 |
4024 lemma sshiftr1_div_2: "sint (sshiftr1 w) = sint w div 2" |
4000 lemma sshiftr1_div_2: "sint (sshiftr1 w) = sint w div 2" |
4025 by transfer simp |
4001 using sint_signed_drop_bit_eq [of 1 w] |
|
4002 by (simp add: drop_bit_Suc sshiftr1_eq_signed_drop_bit_Suc_0) |
4026 |
4003 |
4027 lemma shiftr_div_2n: "uint (shiftr w n) = uint w div 2 ^ n" |
4004 lemma shiftr_div_2n: "uint (shiftr w n) = uint w div 2 ^ n" |
4028 apply (unfold shiftr_def) |
4005 by (fact uint_shiftr_eq) |
4029 apply (induct n) |
|
4030 apply simp |
|
4031 apply (simp add: shiftr1_div_2 mult.commute zdiv_zmult2_eq [symmetric]) |
|
4032 done |
|
4033 |
4006 |
4034 lemma sshiftr_div_2n: "sint (sshiftr w n) = sint w div 2 ^ n" |
4007 lemma sshiftr_div_2n: "sint (sshiftr w n) = sint w div 2 ^ n" |
4035 apply transfer |
4008 using sint_signed_drop_bit_eq [of n w] |
4036 apply (rule bit_eqI) |
4009 by (simp add: drop_bit_eq_div sshiftr_eq) |
4037 apply (simp add: bit_signed_take_bit_iff bit_drop_bit_eq min_def flip: drop_bit_eq_div) |
|
4038 done |
|
4039 |
4010 |
4040 lemma bit_bshiftr1_iff: |
4011 lemma bit_bshiftr1_iff: |
4041 \<open>bit (bshiftr1 b w) n \<longleftrightarrow> b \<and> n = LENGTH('a) - 1 \<or> bit w (Suc n)\<close> |
4012 \<open>bit (bshiftr1 b w) n \<longleftrightarrow> b \<and> n = LENGTH('a) - 1 \<or> bit w (Suc n)\<close> |
4042 for w :: \<open>'a::len word\<close> |
4013 for w :: \<open>'a::len word\<close> |
4043 apply transfer |
4014 apply transfer |
4090 for w :: "'a::len word" |
4061 for w :: "'a::len word" |
4091 by (induct n) (auto simp: shiftl_def shiftl1_2t) |
4062 by (induct n) (auto simp: shiftl_def shiftl1_2t) |
4092 |
4063 |
4093 lemma shiftr1_bintr [simp]: |
4064 lemma shiftr1_bintr [simp]: |
4094 "(shiftr1 (numeral w) :: 'a::len word) = |
4065 "(shiftr1 (numeral w) :: 'a::len word) = |
4095 word_of_int (bin_rest (take_bit (LENGTH('a)) (numeral w)))" |
4066 word_of_int (take_bit LENGTH('a) (numeral w) div 2)" |
4096 by transfer simp |
4067 by transfer simp |
4097 |
4068 |
4098 lemma sshiftr1_sbintr [simp]: |
4069 lemma sshiftr1_sbintr [simp]: |
4099 "(sshiftr1 (numeral w) :: 'a::len word) = |
4070 "(sshiftr1 (numeral w) :: 'a::len word) = |
4100 word_of_int (bin_rest (signed_take_bit (LENGTH('a) - 1) (numeral w)))" |
4071 word_of_int (signed_take_bit (LENGTH('a) - 1) (numeral w) div 2)" |
4101 by transfer simp |
4072 by transfer simp |
4102 |
4073 |
4103 text \<open>TODO: rules for \<^term>\<open>- (numeral n)\<close>\<close> |
4074 text \<open>TODO: rules for \<^term>\<open>- (numeral n)\<close>\<close> |
4104 |
4075 |
4105 lemma drop_bit_word_numeral [simp]: |
4076 lemma drop_bit_word_numeral [simp]: |
4114 lemma sshiftr_numeral [simp]: |
4085 lemma sshiftr_numeral [simp]: |
4115 \<open>(numeral k >>> numeral n :: 'a::len word) = |
4086 \<open>(numeral k >>> numeral n :: 'a::len word) = |
4116 word_of_int (drop_bit (numeral n) (signed_take_bit (LENGTH('a) - 1) (numeral k)))\<close> |
4087 word_of_int (drop_bit (numeral n) (signed_take_bit (LENGTH('a) - 1) (numeral k)))\<close> |
4117 apply (rule word_eqI) |
4088 apply (rule word_eqI) |
4118 apply (cases \<open>LENGTH('a)\<close>) |
4089 apply (cases \<open>LENGTH('a)\<close>) |
4119 apply (simp_all add: word_size bit_drop_bit_eq nth_sshiftr nth_sbintr not_le not_less less_Suc_eq_le ac_simps) |
4090 apply (simp_all add: word_size bit_drop_bit_eq nth_sshiftr bit_signed_take_bit_iff min_def not_le not_less less_Suc_eq_le ac_simps) |
4120 done |
4091 done |
4121 |
4092 |
4122 lemma zip_replicate: "n \<ge> length ys \<Longrightarrow> zip (replicate n x) ys = map (\<lambda>y. (x, y)) ys" |
4093 lemma zip_replicate: "n \<ge> length ys \<Longrightarrow> zip (replicate n x) ys = map (\<lambda>y. (x, y)) ys" |
4123 apply (induct ys arbitrary: n) |
4094 apply (induct ys arbitrary: n) |
4124 apply simp_all |
4095 apply simp_all |
4183 lemma nth_mask [simp]: |
4154 lemma nth_mask [simp]: |
4184 \<open>(mask n :: 'a::len word) !! i \<longleftrightarrow> i < n \<and> i < size (mask n :: 'a word)\<close> |
4155 \<open>(mask n :: 'a::len word) !! i \<longleftrightarrow> i < n \<and> i < size (mask n :: 'a word)\<close> |
4185 by (auto simp add: test_bit_word_eq word_size Word.bit_mask_iff) |
4156 by (auto simp add: test_bit_word_eq word_size Word.bit_mask_iff) |
4186 |
4157 |
4187 lemma mask_bin: "mask n = word_of_int (take_bit n (- 1))" |
4158 lemma mask_bin: "mask n = word_of_int (take_bit n (- 1))" |
4188 by (auto simp add: nth_bintr word_size intro: word_eqI) |
4159 by transfer (simp add: take_bit_minus_one_eq_mask) |
4189 |
4160 |
4190 lemma and_mask_bintr: "w AND mask n = word_of_int (take_bit n (uint w))" |
4161 lemma and_mask_bintr: "w AND mask n = word_of_int (take_bit n (uint w))" |
4191 apply (rule word_eqI) |
4162 by transfer (simp add: ac_simps take_bit_eq_mask) |
4192 apply (simp add: nth_bintr word_size word_ops_nth_size) |
|
4193 apply (auto simp add: test_bit_bin) |
|
4194 done |
|
4195 |
4163 |
4196 lemma and_mask_wi: "word_of_int i AND mask n = word_of_int (take_bit n i)" |
4164 lemma and_mask_wi: "word_of_int i AND mask n = word_of_int (take_bit n i)" |
4197 by (auto simp add: nth_bintr word_size word_ops_nth_size word_eq_iff) |
4165 by (auto simp add: and_mask_bintr min_def not_le wi_bintr) |
4198 |
4166 |
4199 lemma and_mask_wi': |
4167 lemma and_mask_wi': |
4200 "word_of_int i AND mask n = (word_of_int (take_bit (min LENGTH('a) n) i) :: 'a::len word)" |
4168 "word_of_int i AND mask n = (word_of_int (take_bit (min LENGTH('a) n) i) :: 'a::len word)" |
4201 by (auto simp add: nth_bintr word_size word_ops_nth_size word_eq_iff) |
4169 by (auto simp add: and_mask_wi min_def wi_bintr) |
4202 |
4170 |
4203 lemma and_mask_no: "numeral i AND mask n = word_of_int (take_bit n (numeral i))" |
4171 lemma and_mask_no: "numeral i AND mask n = word_of_int (take_bit n (numeral i))" |
4204 unfolding word_numeral_alt by (rule and_mask_wi) |
4172 unfolding word_numeral_alt by (rule and_mask_wi) |
4205 |
4173 |
4206 lemma and_mask_mod_2p: "w AND mask n = word_of_int (uint w mod 2 ^ n)" |
4174 lemma and_mask_mod_2p: "w AND mask n = word_of_int (uint w mod 2 ^ n)" |
4209 lemma uint_mask_eq: |
4177 lemma uint_mask_eq: |
4210 \<open>uint (mask n :: 'a::len word) = mask (min LENGTH('a) n)\<close> |
4178 \<open>uint (mask n :: 'a::len word) = mask (min LENGTH('a) n)\<close> |
4211 by transfer simp |
4179 by transfer simp |
4212 |
4180 |
4213 lemma and_mask_lt_2p: "uint (w AND mask n) < 2 ^ n" |
4181 lemma and_mask_lt_2p: "uint (w AND mask n) < 2 ^ n" |
4214 apply (simp add: uint_and uint_mask_eq) |
4182 apply (simp flip: take_bit_eq_mask) |
4215 apply (rule AND_upper2'') |
4183 apply transfer |
4216 apply simp |
4184 apply (auto simp add: min_def) |
4217 apply (auto simp add: mask_eq_exp_minus_1 min_def power_add algebra_simps dest!: le_Suc_ex) |
4185 using antisym_conv take_bit_int_eq_self_iff by fastforce |
4218 apply (metis add_minus_cancel le_add2 one_le_numeral power_add power_increasing uminus_add_conv_diff zle_diff1_eq) |
|
4219 done |
|
4220 |
|
4221 lemma eq_mod_iff: "0 < n \<Longrightarrow> b = b mod n \<longleftrightarrow> 0 \<le> b \<and> b < n" |
|
4222 for b n :: int |
|
4223 by auto (metis pos_mod_conj)+ |
|
4224 |
4186 |
4225 lemma mask_eq_iff: "w AND mask n = w \<longleftrightarrow> uint w < 2 ^ n" |
4187 lemma mask_eq_iff: "w AND mask n = w \<longleftrightarrow> uint w < 2 ^ n" |
4226 apply (auto simp flip: take_bit_eq_mask) |
4188 apply (auto simp flip: take_bit_eq_mask) |
4227 apply (metis take_bit_int_eq_self_iff uint_take_bit_eq) |
4189 apply (metis take_bit_int_eq_self_iff uint_take_bit_eq) |
4228 apply (simp add: take_bit_int_eq_self unsigned_take_bit_eq word_uint_eqI) |
4190 apply (simp add: take_bit_int_eq_self unsigned_take_bit_eq word_uint_eqI) |
4238 for w :: "'a::len word" |
4200 for w :: "'a::len word" |
4239 by transfer simp |
4201 by transfer simp |
4240 |
4202 |
4241 lemma less_mask_eq: "x < 2 ^ n \<Longrightarrow> x AND mask n = x" |
4203 lemma less_mask_eq: "x < 2 ^ n \<Longrightarrow> x AND mask n = x" |
4242 for x :: "'a::len word" |
4204 for x :: "'a::len word" |
4243 apply (simp add: and_mask_bintr) |
4205 apply (cases \<open>n < LENGTH('a)\<close>) |
|
4206 apply (simp_all add: not_less flip: take_bit_eq_mask exp_eq_zero_iff) |
4244 apply transfer |
4207 apply transfer |
4245 apply (simp add: ac_simps) |
4208 apply (simp add: min_def) |
4246 apply (auto simp add: min_def) |
4209 apply (metis min_def nat_less_le take_bit_int_eq_self_iff take_bit_take_bit) |
4247 apply (metis bintrunc_bintrunc_ge mod_pos_pos_trivial mult.commute mult.left_neutral mult_zero_left not_le of_bool_def take_bit_eq_mod take_bit_nonnegative) |
|
4248 done |
4210 done |
4249 |
4211 |
4250 lemmas mask_eq_iff_w2p = trans [OF mask_eq_iff word_2p_lem [symmetric]] |
4212 lemmas mask_eq_iff_w2p = trans [OF mask_eq_iff word_2p_lem [symmetric]] |
4251 |
4213 |
4252 lemmas and_mask_less' = iffD2 [OF word_2p_lem and_mask_lt_2p, simplified word_size] |
4214 lemmas and_mask_less' = iffD2 [OF word_2p_lem and_mask_lt_2p, simplified word_size] |
4542 (if n < size b then b !! n else a !! (n - size b)))" |
4504 (if n < size b then b !! n else a !! (n - size b)))" |
4543 apply (simp add: word_size not_less; transfer) |
4505 apply (simp add: word_size not_less; transfer) |
4544 apply (auto simp add: bit_concat_bit_iff bit_take_bit_iff) |
4506 apply (auto simp add: bit_concat_bit_iff bit_take_bit_iff) |
4545 done |
4507 done |
4546 |
4508 |
4547 lemma split_uint_lem: "bin_split n (uint w) = (a, b) \<Longrightarrow> |
|
4548 a = take_bit (LENGTH('a) - n) a \<and> b = take_bit (LENGTH('a)) b" |
|
4549 for w :: "'a::len word" |
|
4550 by transfer (simp add: drop_bit_take_bit ac_simps) |
|
4551 |
|
4552 \<comment> \<open>keep quantifiers for use in simplification\<close> |
4509 \<comment> \<open>keep quantifiers for use in simplification\<close> |
4553 lemma test_bit_split': |
4510 lemma test_bit_split': |
4554 "word_split c = (a, b) \<longrightarrow> |
4511 "word_split c = (a, b) \<longrightarrow> |
4555 (\<forall>n m. |
4512 (\<forall>n m. |
4556 b !! n = (n < size b \<and> c !! n) \<and> |
4513 b !! n = (n < size b \<and> c !! n) \<and> |
4557 a !! m = (m < size a \<and> c !! (m + size b)))" |
4514 a !! m = (m < size a \<and> c !! (m + size b)))" |
4558 apply (unfold word_split_bin' test_bit_bin) |
4515 by (auto simp add: word_split_bin' test_bit_bin bit_unsigned_iff word_size |
4559 apply (clarify) |
4516 bit_drop_bit_eq ac_simps exp_eq_zero_iff |
4560 apply simp |
4517 dest: bit_imp_le_length) |
4561 apply (erule conjE) |
|
4562 apply (drule sym) |
|
4563 apply (drule sym) |
|
4564 apply (simp add: bit_take_bit_iff bit_drop_bit_eq) |
|
4565 apply transfer |
|
4566 apply (simp add: bit_take_bit_iff ac_simps) |
|
4567 done |
|
4568 |
4518 |
4569 lemma test_bit_split: |
4519 lemma test_bit_split: |
4570 "word_split c = (a, b) \<Longrightarrow> |
4520 "word_split c = (a, b) \<Longrightarrow> |
4571 (\<forall>n::nat. b !! n \<longleftrightarrow> n < size b \<and> c !! n) \<and> |
4521 (\<forall>n::nat. b !! n \<longleftrightarrow> n < size b \<and> c !! n) \<and> |
4572 (\<forall>m::nat. a !! m \<longleftrightarrow> m < size a \<and> c !! (m + size b))" |
4522 (\<forall>m::nat. a !! m \<longleftrightarrow> m < size a \<and> c !! (m + size b))" |
4588 |
4538 |
4589 \<comment> \<open>this odd result is analogous to \<open>ucast_id\<close>, |
4539 \<comment> \<open>this odd result is analogous to \<open>ucast_id\<close>, |
4590 result to the length given by the result type\<close> |
4540 result to the length given by the result type\<close> |
4591 |
4541 |
4592 lemma word_cat_id: "word_cat a b = b" |
4542 lemma word_cat_id: "word_cat a b = b" |
4593 by transfer simp |
4543 by transfer (simp add: take_bit_concat_bit_eq) |
4594 |
|
4595 \<comment> \<open>limited hom result\<close> |
|
4596 lemma word_cat_hom: |
|
4597 "LENGTH('a::len) \<le> LENGTH('b::len) + LENGTH('c::len) \<Longrightarrow> |
|
4598 (word_cat (word_of_int w :: 'b word) (b :: 'c word) :: 'a word) = |
|
4599 word_of_int (bin_cat w (size b) (uint b))" |
|
4600 apply transfer |
|
4601 using bintr_cat by auto |
|
4602 |
4544 |
4603 lemma word_cat_split_alt: "size w \<le> size u + size v \<Longrightarrow> word_split w = (u, v) \<Longrightarrow> word_cat u v = w" |
4545 lemma word_cat_split_alt: "size w \<le> size u + size v \<Longrightarrow> word_split w = (u, v) \<Longrightarrow> word_cat u v = w" |
4604 apply (rule word_eqI) |
4546 apply (rule word_eqI) |
4605 apply (drule test_bit_split) |
4547 apply (drule test_bit_split) |
4606 apply (clarsimp simp add : test_bit_cat word_size) |
4548 apply (clarsimp simp add : test_bit_cat word_size) |
4673 |
4615 |
4674 lemma test_bit_rcat: |
4616 lemma test_bit_rcat: |
4675 "sw = size (hd wl) \<Longrightarrow> rc = word_rcat wl \<Longrightarrow> rc !! n = |
4617 "sw = size (hd wl) \<Longrightarrow> rc = word_rcat wl \<Longrightarrow> rc !! n = |
4676 (n < size rc \<and> n div sw < size wl \<and> (rev wl) ! (n div sw) !! (n mod sw))" |
4618 (n < size rc \<and> n div sw < size wl \<and> (rev wl) ! (n div sw) !! (n mod sw))" |
4677 for wl :: "'a::len word list" |
4619 for wl :: "'a::len word list" |
4678 by (simp add: word_size word_rcat_def bin_rcat_def foldl_map rev_map bit_horner_sum_uint_exp_iff) |
4620 by (simp add: word_size word_rcat_def foldl_map rev_map bit_horner_sum_uint_exp_iff) |
4679 (simp add: test_bit_eq_bit) |
4621 (simp add: test_bit_eq_bit) |
4680 |
4622 |
4681 lemmas test_bit_cong = arg_cong [where f = "test_bit", THEN fun_cong] |
4623 lemmas test_bit_cong = arg_cong [where f = "test_bit", THEN fun_cong] |
4682 |
4624 |
4683 |
4625 |
4930 proof - |
4872 proof - |
4931 from that have \<open>unat b \<le> unat a\<close> |
4873 from that have \<open>unat b \<le> unat a\<close> |
4932 by transfer simp |
4874 by transfer simp |
4933 with that show ?thesis |
4875 with that show ?thesis |
4934 apply transfer |
4876 apply transfer |
4935 apply simp |
4877 apply simp |
4936 apply (subst take_bit_diff [symmetric]) |
4878 apply (subst take_bit_diff [symmetric]) |
4937 apply (subst nat_take_bit_eq) |
4879 apply (subst nat_take_bit_eq) |
4938 apply (simp add: nat_le_eq_zle) |
4880 apply (simp add: nat_le_eq_zle) |
4939 apply (simp add: nat_diff_distrib take_bit_nat_eq_self_iff less_imp_diff_less bintr_lt2p) |
4881 apply (simp add: nat_diff_distrib take_bit_nat_eq_self_iff less_imp_diff_less) |
4940 done |
4882 done |
4941 qed |
4883 qed |
4942 |
4884 |
4943 lemmas word_less_sub1_numberof [simp] = word_less_sub1 [of "numeral w"] for w |
4885 lemmas word_less_sub1_numberof [simp] = word_less_sub1 [of "numeral w"] for w |
4944 lemmas word_le_sub1_numberof [simp] = word_le_sub1 [of "numeral w"] for w |
4886 lemmas word_le_sub1_numberof [simp] = word_le_sub1 [of "numeral w"] for w |
5143 by transfer (simp add: min_def mask_Suc_exp) |
5085 by transfer (simp add: min_def mask_Suc_exp) |
5144 |
5086 |
5145 lemma mask_Suc_0: "mask (Suc 0) = 1" |
5087 lemma mask_Suc_0: "mask (Suc 0) = 1" |
5146 using mask_1 by simp |
5088 using mask_1 by simp |
5147 |
5089 |
5148 lemma bin_last_bintrunc: "bin_last (take_bit l n) = (l > 0 \<and> bin_last n)" |
5090 lemma bin_last_bintrunc: "odd (take_bit l n) \<longleftrightarrow> l > 0 \<and> odd n" |
5149 by simp |
5091 by simp |
5150 |
5092 |
5151 lemma word_and_1: |
5093 lemma word_and_1: |
5152 "n AND 1 = (if n !! 0 then 1 else 0)" for n :: "_ word" |
5094 "n AND 1 = (if n !! 0 then 1 else 0)" for n :: "_ word" |
5153 by (rule bit_word_eqI) (auto simp add: bit_and_iff test_bit_eq_bit bit_1_iff intro: gr0I) |
5095 by (rule bit_word_eqI) (auto simp add: bit_and_iff test_bit_eq_bit bit_1_iff intro: gr0I) |
5154 |
5096 |
5155 lemma bintrunc_shiftl: |
|
5156 "take_bit n (m << i) = take_bit (n - i) m << i" |
|
5157 for m :: int |
|
5158 by (rule bit_eqI) (auto simp add: bit_take_bit_iff) |
|
5159 |
|
5160 lemma uint_shiftl: |
|
5161 "uint (n << i) = take_bit (size n) (uint n << i)" |
|
5162 by transfer (simp add: push_bit_take_bit shiftl_eq_push_bit) |
|
5163 |
|
5164 |
5097 |
5165 subsection \<open>Misc\<close> |
5098 subsection \<open>Misc\<close> |
5166 |
5099 |
5167 ML_file \<open>Tools/word_lib.ML\<close> |
5100 ML_file \<open>Tools/word_lib.ML\<close> |
5168 ML_file \<open>Tools/smt_word.ML\<close> |
5101 ML_file \<open>Tools/smt_word.ML\<close> |