# HG changeset patch # User haftmann # Date 1599468448 0 # Node ID bb002df3e82e3944021024f0c8578d1d1c3649a5 # Parent 5a6d8675bf4b72550e73a2b545205ee01d53a561 more on conversions diff -r 5a6d8675bf4b -r bb002df3e82e src/HOL/Word/Conversions.thy --- a/src/HOL/Word/Conversions.thy Sat Sep 05 16:21:16 2020 +0000 +++ b/src/HOL/Word/Conversions.thy Mon Sep 07 08:47:28 2020 +0000 @@ -13,6 +13,41 @@ hide_const (open) unat uint sint word_of_int ucast scast +context semiring_bits +begin + +lemma + exp_add_not_zero_imp_left: \2 ^ m \ 0\ + and exp_add_not_zero_imp_right: \2 ^ n \ 0\ if \2 ^ (m + n) \ 0\ +proof - + have \\ (2 ^ m = 0 \ 2 ^ n = 0)\ + proof (rule notI) + assume \2 ^ m = 0 \ 2 ^ n = 0\ + then have \2 ^ (m + n) = 0\ + by (rule disjE) (simp_all add: power_add) + with that show False .. + qed + then show \2 ^ m \ 0\ and \2 ^ n \ 0\ + by simp_all +qed + +lemma exp_not_zero_imp_exp_diff_not_zero: + \2 ^ (n - m) \ 0\ if \2 ^ n \ 0\ +proof (cases \m \ n\) + case True + moreover define q where \q = n - m\ + ultimately have \n = m + q\ + by simp + with that show ?thesis + by (simp add: exp_add_not_zero_imp_right) +next + case False + with that show ?thesis + by simp +qed + +end + subsection \Conversions to word\ @@ -246,8 +281,7 @@ (auto simp add: bit_of_int_iff Bit_Operations.bit_signed_take_bit_iff min_def) lemma signed_push_bit_eq: - \signed (push_bit n w) = take_bit (LENGTH('b) - Suc 0) (push_bit n (signed w)) - OR of_bool (n < LENGTH('b) \ bit w (LENGTH('b) - Suc n)) * NOT (mask (LENGTH('b) - Suc 0))\ + \signed (push_bit n w) = signed_take_bit (LENGTH('b) - 1) (push_bit n (signed w :: 'a))\ for w :: \'b::len word\ proof (rule bit_eqI) fix m @@ -256,18 +290,27 @@ then have *: \LENGTH('b) = Suc q\ by simp show \bit (signed (push_bit n w)) m \ - bit (take_bit (LENGTH('b) - Suc 0) (push_bit n (signed w)) OR - of_bool (n < LENGTH('b) \ bit w (LENGTH('b) - Suc n)) * NOT (mask (LENGTH('b) - Suc 0))) m\ - proof (cases \n \ m\) + bit (signed_take_bit (LENGTH('b) - 1) (push_bit n (signed w :: 'a))) m\ + proof (cases \q \ m\) case True - with \2 ^ m \ 0\ have \2 ^ (m - n) \ 0\ - by (metis (full_types) diff_add exp_add_not_zero_imp) - with True show ?thesis - by (auto simp add: * bit_signed_iff bit_push_bit_iff Parity.bit_push_bit_iff bit_or_iff bit_take_bit_iff bit_not_iff bit_mask_iff exp_eq_zero_iff min_def) + moreover define r where \r = m - q\ + ultimately have \m = q + r\ + by simp + moreover from \m = q + r\ \2 ^ m \ 0\ have \2 ^ q \ 0\ \2 ^ r \ 0\ + using exp_add_not_zero_imp_left [of q r] exp_add_not_zero_imp_right [of q r] + by simp_all + moreover from \2 ^ q \ 0\ have \2 ^ (q - n) \ 0\ + by (rule exp_not_zero_imp_exp_diff_not_zero) + ultimately show ?thesis + by (auto simp add: bit_signed_iff bit_signed_take_bit_iff bit_push_bit_iff Parity.bit_push_bit_iff + min_def * exp_eq_zero_iff le_diff_conv2) next case False then show ?thesis - by (simp add: * bit_signed_iff bit_push_bit_iff Parity.bit_push_bit_iff bit_or_iff bit_take_bit_iff bit_not_iff bit_mask_iff) + using exp_not_zero_imp_exp_diff_not_zero [of m n] + by (auto simp add: bit_signed_iff bit_signed_take_bit_iff bit_push_bit_iff Parity.bit_push_bit_iff + 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 + exp_eq_zero_iff) qed qed @@ -278,27 +321,32 @@ (auto simp add: Bit_Operations.signed_take_bit_take_bit Bit_Operations.take_bit_signed_take_bit take_bit_of_int min_def less_Suc_eq) lemma signed_not_eq: - \signed (NOT w) = take_bit LENGTH('b) (NOT (signed w)) OR of_bool (bit (NOT (signed w)) LENGTH('b)) * NOT (mask LENGTH('b))\ + \signed (NOT w) = signed_take_bit LENGTH('b) (NOT (signed w))\ for w :: \'b::len word\ proof (rule bit_eqI) fix n assume \2 ^ n \ 0\ + define q where \q = LENGTH('b) - Suc 0\ + then have *: \LENGTH('b) = Suc q\ + by simp show \bit (signed (NOT w)) n \ - bit (take_bit LENGTH('b) (NOT (signed w)) OR - of_bool (bit (NOT (signed w)) LENGTH('b)) * NOT (mask LENGTH('b))) n\ - proof (cases \LENGTH('b) \ n\) + bit (signed_take_bit LENGTH('b) (NOT (signed w))) n\ + proof (cases \q < n\) + case True + moreover define r where \r = n - Suc q\ + ultimately have \n = r + Suc q\ + by simp + moreover from \2 ^ n \ 0\ \n = r + Suc q\ + have \2 ^ Suc q \ 0\ + using exp_add_not_zero_imp_right by blast + ultimately show ?thesis + by (simp add: * bit_signed_iff bit_not_iff bit_signed_take_bit_iff Bit_Operations.bit_not_iff min_def + exp_eq_zero_iff) + next case False then show ?thesis - by (auto simp add: bit_signed_iff bit_not_iff bit_or_iff bit_take_bit_iff bit_mask_iff Bit_Operations.bit_not_iff exp_eq_zero_iff) - next - case True - moreover define q where \q = n - LENGTH('b)\ - ultimately have \n = LENGTH('b) + q\ - by simp - with \2 ^ n \ 0\ have \2 ^ q \ 0\ \2 ^ LENGTH('b) \ 0\ - by (simp_all add: power_add) (use mult_not_zero in blast)+ - then show ?thesis - by (simp add: bit_signed_iff bit_not_iff bit_or_iff bit_take_bit_iff bit_mask_iff Bit_Operations.bit_not_iff exp_eq_zero_iff min_def not_le not_less le_diff_conv le_Suc_eq) + by (auto simp add: * bit_signed_iff bit_not_iff bit_signed_take_bit_iff Bit_Operations.bit_not_iff min_def + exp_eq_zero_iff) qed qed @@ -445,31 +493,6 @@ \of_int (sint a) = signed a\ by transfer (simp_all add: take_bit_signed_take_bit) -lemma sint_not_eq: - \sint (NOT w) = signed_take_bit LENGTH('a) (NOT (sint w))\ - for w :: \'a::len word\ - by (simp add: signed_not_eq signed_take_bit_def) - -lemma sint_push_bit_eq: - \signed (push_bit n w) = signed_take_bit (LENGTH('a) - Suc 0) (push_bit n (signed w))\ - for w :: \'a::len word\ - apply (transfer fixing: n; cases \LENGTH('a)\) - apply simp_all - apply (rule bit_eqI) - apply (simp add: bit_of_int_iff bit_signed_take_bit_iff bit_push_bit_iff min_def not_le le_diff_conv2) - apply auto - apply (metis le_add_diff_inverse mult_zero_left power_add) - apply (metis (no_types, lifting) diff_le_self le_add_diff_inverse mult_zero_left power_add) - using diff_diff_cancel apply fastforce - using diff_diff_cancel apply fastforce - apply (metis add_diff_cancel_right' diff_commute diff_le_self le_antisym less_imp_add_positive) - apply (metis le_add_diff_inverse mult_zero_left power_add) - apply (metis (no_types, lifting) diff_le_self le_add_diff_inverse mult_zero_left power_add) - apply (metis add.commute le_Suc_ex mult_zero_right power_add) - apply (metis le_add_diff_inverse mult_zero_left mult_zero_right power_add) - apply (metis le_add_diff_inverse mult_zero_right power_add) - done - lemma sint_greater_eq: \- (2 ^ (LENGTH('a) - Suc 0)) \ sint w\ for w :: \'a::len word\ proof (cases \bit w (LENGTH('a) - Suc 0)\) @@ -489,21 +512,44 @@ by (cases \bit w (LENGTH('a) - Suc 0)\; transfer) (simp_all add: signed_take_bit_eq signed_take_bit_def take_bit_int_less_exp not_eq_complement mask_eq_exp_minus_1 OR_upper) -context semiring_1 +context semiring_bit_shifts +begin + +lemma unsigned_ucast_eq: + \unsigned (ucast w :: 'c::len word) = take_bit LENGTH('c) (unsigned w)\ + for w :: \'b::len word\ + by (rule bit_eqI) (simp add: bit_unsigned_iff Conversions.bit_unsigned_iff bit_take_bit_iff exp_eq_zero_iff not_le) + +end + +context ring_bit_operations begin -lemma unsigned_ucase_eq: - \unsigned (ucast w :: 'c::len word) = unsigned (take_bit LENGTH('c) w)\ +lemma signed_ucast_eq: + \signed (ucast w :: 'c::len word) = signed_take_bit (LENGTH('c) - Suc 0) (unsigned w)\ for w :: \'b::len word\ - by transfer (simp add: ac_simps) +proof (rule bit_eqI) + fix n + assume \2 ^ n \ 0\ + then have \2 ^ (min (LENGTH('c) - Suc 0) n) \ 0\ + by (simp add: min_def) + (metis (mono_tags) diff_diff_cancel local.exp_not_zero_imp_exp_diff_not_zero) + then show \bit (signed (ucast w :: 'c::len word)) n \ bit (signed_take_bit (LENGTH('c) - Suc 0) (unsigned w)) n\ + by (simp add: bit_signed_iff bit_unsigned_iff Conversions.bit_unsigned_iff bit_signed_take_bit_iff exp_eq_zero_iff not_le) +qed -lemma signed_ucast_eq: - \signed (ucast w :: 'c::len word) = - take_bit (min LENGTH('b) LENGTH('c)) w OR of_bool (bit w (LENGTH('c) - Suc 0)) * NOT (mask LENGTH('c))\ +lemma signed_scast_eq: + \signed (scast w :: 'c::len word) = signed_take_bit (LENGTH('c) - Suc 0) (signed w)\ for w :: \'b::len word\ - by (transfer, rule bit_eqI) - (simp_all add: bit_take_bit_iff bit_signed_take_bit_iff bit_or_iff bit_not_iff bit_mask_iff - not_less not_le min_def le_diff_conv less_diff_conv2 le_Suc_eq) +proof (rule bit_eqI) + fix n + assume \2 ^ n \ 0\ + then have \2 ^ (min (LENGTH('c) - Suc 0) n) \ 0\ + by (simp add: min_def) + (metis (mono_tags) diff_diff_cancel local.exp_not_zero_imp_exp_diff_not_zero) + then show \bit (signed (scast w :: 'c::len word)) n \ bit (signed_take_bit (LENGTH('c) - Suc 0) (signed w)) n\ + by (simp add: bit_signed_iff bit_unsigned_iff Conversions.bit_signed_iff bit_signed_take_bit_iff exp_eq_zero_iff not_le) +qed end diff -r 5a6d8675bf4b -r bb002df3e82e src/HOL/Word/Word.thy --- a/src/HOL/Word/Word.thy Sat Sep 05 16:21:16 2020 +0000 +++ b/src/HOL/Word/Word.thy Mon Sep 07 08:47:28 2020 +0000 @@ -1042,6 +1042,22 @@ \((=) ===> pcr_word ===> pcr_word) flip_bit flip_bit\ by (unfold flip_bit_def) transfer_prover +lemma signed_take_bit_word_transfer [transfer_rule]: + \((=) ===> pcr_word ===> pcr_word) + (\n k. signed_take_bit n (take_bit LENGTH('a::len) k)) + (signed_take_bit :: nat \ 'a word \ 'a word)\ +proof - + let ?K = \\n (k :: int). take_bit (min LENGTH('a) n) k OR of_bool (n < LENGTH('a) \ bit k n) * NOT (mask n)\ + let ?W = \\n (w :: 'a word). take_bit n w OR of_bool (bit w n) * NOT (mask n)\ + have \((=) ===> pcr_word ===> pcr_word) ?K ?W\ + by transfer_prover + also have \?K = (\n k. signed_take_bit n (take_bit LENGTH('a::len) k))\ + by (simp add: fun_eq_iff signed_take_bit_def bit_take_bit_iff ac_simps) + also have \?W = signed_take_bit\ + by (simp add: fun_eq_iff signed_take_bit_def) + finally show ?thesis . +qed + end instantiation word :: (len) semiring_bit_syntax