# HG changeset patch # User haftmann # Date 1598800528 0 # Node ID 0f3d24dc197f144741b49d51719e3e5c7ad035c4 # Parent 5e26a4bca0c2d9f370c127213a159c6b87bd91d9 more on conversions diff -r 5e26a4bca0c2 -r 0f3d24dc197f src/HOL/Library/Bit_Operations.thy --- a/src/HOL/Library/Bit_Operations.thy Sat Aug 29 16:30:33 2020 +0100 +++ b/src/HOL/Library/Bit_Operations.thy Sun Aug 30 15:15:28 2020 +0000 @@ -737,15 +737,92 @@ qed qed +context ring_bit_operations +begin + +lemma even_of_int_iff: + \even (of_int k) \ even k\ + by (induction k rule: int_bit_induct) simp_all + +lemma bit_of_int_iff: + \bit (of_int k) n \ (2::'a) ^ n \ 0 \ bit k n\ +proof (cases \(2::'a) ^ n = 0\) + case True + then show ?thesis + by (simp add: exp_eq_0_imp_not_bit) +next + case False + then have \bit (of_int k) n \ bit k n\ + proof (induction k arbitrary: n rule: int_bit_induct) + case zero + then show ?case + by simp + next + case minus + then show ?case + by simp + next + case (even k) + then show ?case + using bit_double_iff [of \of_int k\ n] Parity.bit_double_iff [of k n] + by (cases n) (auto simp add: ac_simps dest: mult_not_zero) + next + case (odd k) + then show ?case + using bit_double_iff [of \of_int k\ n] + by (cases n) (auto simp add: ac_simps bit_double_iff even_bit_succ_iff Parity.bit_Suc dest: mult_not_zero) + qed + with False show ?thesis + by simp +qed + +lemma push_bit_of_int: + \push_bit n (of_int k) = of_int (push_bit n k)\ + by (simp add: push_bit_eq_mult semiring_bit_shifts_class.push_bit_eq_mult) + +lemma of_int_push_bit: + \of_int (push_bit n k) = push_bit n (of_int k)\ + by (simp add: push_bit_eq_mult semiring_bit_shifts_class.push_bit_eq_mult) + +lemma take_bit_of_int: + \take_bit n (of_int k) = of_int (take_bit n k)\ + by (rule bit_eqI) (simp add: bit_take_bit_iff Parity.bit_take_bit_iff bit_of_int_iff) + +lemma of_int_take_bit: + \of_int (take_bit n k) = take_bit n (of_int k)\ + by (rule bit_eqI) (simp add: bit_take_bit_iff Parity.bit_take_bit_iff bit_of_int_iff) + +lemma of_int_not_eq: + \of_int (NOT k) = NOT (of_int k)\ + by (rule bit_eqI) (simp add: bit_not_iff Bit_Operations.bit_not_iff bit_of_int_iff) + +lemma of_int_and_eq: + \of_int (k AND l) = of_int k AND of_int l\ + by (rule bit_eqI) (simp add: bit_of_int_iff bit_and_iff Bit_Operations.bit_and_iff) + +lemma of_int_or_eq: + \of_int (k OR l) = of_int k OR of_int l\ + by (rule bit_eqI) (simp add: bit_of_int_iff bit_or_iff Bit_Operations.bit_or_iff) + +lemma of_int_xor_eq: + \of_int (k XOR l) = of_int k XOR of_int l\ + by (rule bit_eqI) (simp add: bit_of_int_iff bit_xor_iff Bit_Operations.bit_xor_iff) + +lemma of_int_mask_eq: + \of_int (mask n) = mask n\ + by (induction n) (simp_all add: mask_Suc_double Bit_Operations.mask_Suc_double of_int_or_eq) + +end + subsection \Bit concatenation\ definition concat_bit :: \nat \ int \ int \ int\ - where \concat_bit n k l = (k AND mask n) OR push_bit n l\ + where \concat_bit n k l = take_bit n k OR push_bit n l\ lemma bit_concat_bit_iff: \bit (concat_bit m k l) n \ n < m \ bit k n \ m \ n \ bit l (n - m)\ - by (simp add: concat_bit_def bit_or_iff bit_and_iff bit_mask_iff bit_push_bit_iff ac_simps) + by (simp add: concat_bit_def bit_or_iff bit_and_iff bit_take_bit_iff bit_push_bit_iff ac_simps) lemma concat_bit_eq: \concat_bit n k l = take_bit n k + push_bit n l\ @@ -784,12 +861,52 @@ \concat_bit m (concat_bit n k l) r = concat_bit (min m n) k (concat_bit (m - n) l r)\ by (rule bit_eqI) (auto simp add: bit_concat_bit_iff ac_simps min_def) +lemma concat_bit_eq_iff: + \concat_bit n k l = concat_bit n r s + \ take_bit n k = take_bit n r \ l = s\ (is \?P \ ?Q\) +proof + assume ?Q + then show ?P + by (simp add: concat_bit_def) +next + assume ?P + then have *: \bit (concat_bit n k l) m = bit (concat_bit n r s) m\ for m + by (simp add: bit_eq_iff) + have \take_bit n k = take_bit n r\ + proof (rule bit_eqI) + fix m + from * [of m] + show \bit (take_bit n k) m \ bit (take_bit n r) m\ + by (auto simp add: bit_take_bit_iff bit_concat_bit_iff) + qed + moreover have \push_bit n l = push_bit n s\ + proof (rule bit_eqI) + fix m + from * [of m] + show \bit (push_bit n l) m \ bit (push_bit n s) m\ + by (auto simp add: bit_push_bit_iff bit_concat_bit_iff) + qed + then have \l = s\ + by (simp add: push_bit_eq_mult) + ultimately show ?Q + by (simp add: concat_bit_def) +qed + +lemma take_bit_concat_bit_eq: + \take_bit m (concat_bit n k l) = concat_bit (min m n) k (take_bit (m - n) l)\ + by (rule bit_eqI) + (auto simp add: bit_take_bit_iff bit_concat_bit_iff min_def) + subsection \Taking bit with sign propagation\ definition signed_take_bit :: \nat \ int \ int\ where \signed_take_bit n k = concat_bit n k (- of_bool (bit k n))\ +lemma signed_take_bit_unfold: + \signed_take_bit n k = take_bit n k OR (of_bool (bit k n) * NOT (mask n))\ + by (simp add: signed_take_bit_def concat_bit_def push_bit_minus_one_eq_not_mask) + lemma signed_take_bit_eq: \signed_take_bit n k = take_bit n k\ if \\ bit k n\ using that by (simp add: signed_take_bit_def) @@ -1044,11 +1161,11 @@ instance proof fix m n q :: nat show \bit (m AND n) q \ bit m q \ bit n q\ - by (auto simp add: and_nat_def bit_and_iff less_le bit_eq_iff) + by (auto simp add: bit_nat_iff and_nat_def bit_and_iff less_le bit_eq_iff) show \bit (m OR n) q \ bit m q \ bit n q\ - by (auto simp add: or_nat_def bit_or_iff less_le bit_eq_iff) + by (auto simp add: bit_nat_iff or_nat_def bit_or_iff less_le bit_eq_iff) show \bit (m XOR n) q \ bit m q \ bit n q\ - by (auto simp add: xor_nat_def bit_xor_iff less_le bit_eq_iff) + by (auto simp add: bit_nat_iff xor_nat_def bit_xor_iff less_le bit_eq_iff) qed (simp add: mask_nat_def) end @@ -1089,6 +1206,32 @@ \n XOR Suc 0 = n + of_bool (even n) - of_bool (odd n)\ using xor_one_eq [of n] by simp +context semiring_bit_operations +begin + +lemma of_nat_and_eq: + \of_nat (m AND n) = of_nat m AND of_nat n\ + by (rule bit_eqI) (simp add: bit_of_nat_iff bit_and_iff Bit_Operations.bit_and_iff) + +lemma of_nat_or_eq: + \of_nat (m OR n) = of_nat m OR of_nat n\ + by (rule bit_eqI) (simp add: bit_of_nat_iff bit_or_iff Bit_Operations.bit_or_iff) + +lemma of_nat_xor_eq: + \of_nat (m XOR n) = of_nat m XOR of_nat n\ + by (rule bit_eqI) (simp add: bit_of_nat_iff bit_xor_iff Bit_Operations.bit_xor_iff) + +end + +context ring_bit_operations +begin + +lemma of_nat_mask_eq: + \of_nat (mask n) = mask n\ + by (induction n) (simp_all add: mask_Suc_double Bit_Operations.mask_Suc_double of_nat_or_eq) + +end + subsection \Instances for \<^typ>\integer\ and \<^typ>\natural\\ @@ -1224,4 +1367,33 @@ \<^item> (Bounded) conversion from and to a list of bits: @{thm horner_sum_bit_eq_take_bit [where ?'a = int, no_vars]} \ +context semiring_bit_operations +begin + +lemma push_bit_and [simp]: + \push_bit n (a AND b) = push_bit n a AND push_bit n b\ + by (rule bit_eqI) (auto simp add: bit_push_bit_iff bit_and_iff) + +lemma push_bit_or [simp]: + \push_bit n (a OR b) = push_bit n a OR push_bit n b\ + by (rule bit_eqI) (auto simp add: bit_push_bit_iff bit_or_iff) + +lemma push_bit_xor [simp]: + \push_bit n (a XOR b) = push_bit n a XOR push_bit n b\ + by (rule bit_eqI) (auto simp add: bit_push_bit_iff bit_xor_iff) + +lemma drop_bit_and [simp]: + \drop_bit n (a AND b) = drop_bit n a AND drop_bit n b\ + by (rule bit_eqI) (auto simp add: bit_drop_bit_eq bit_and_iff) + +lemma drop_bit_or [simp]: + \drop_bit n (a OR b) = drop_bit n a OR drop_bit n b\ + by (rule bit_eqI) (auto simp add: bit_drop_bit_eq bit_or_iff) + +lemma drop_bit_xor [simp]: + \drop_bit n (a XOR b) = drop_bit n a XOR drop_bit n b\ + by (rule bit_eqI) (auto simp add: bit_drop_bit_eq bit_xor_iff) + end + +end diff -r 5e26a4bca0c2 -r 0f3d24dc197f src/HOL/Parity.thy --- a/src/HOL/Parity.thy Sat Aug 29 16:30:33 2020 +0100 +++ b/src/HOL/Parity.thy Sun Aug 30 15:15:28 2020 +0000 @@ -976,6 +976,20 @@ \bit (numeral Num.One) n \ n = 0\ by (simp add: bit_rec) +lemma exp_add_not_zero_imp: + \2 ^ m \ 0\ and \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 + end lemma nat_bit_induct [case_names zero even odd]: @@ -1111,6 +1125,43 @@ qed qed +context semiring_bits +begin + +lemma even_of_nat_iff: + \even (of_nat n) \ even n\ + by (induction n rule: nat_bit_induct) simp_all + +lemma bit_of_nat_iff: + \bit (of_nat m) n \ (2::'a) ^ n \ 0 \ bit m n\ +proof (cases \(2::'a) ^ n = 0\) + case True + then show ?thesis + by (simp add: exp_eq_0_imp_not_bit) +next + case False + then have \bit (of_nat m) n \ bit m n\ + proof (induction m arbitrary: n rule: nat_bit_induct) + case zero + then show ?case + by simp + next + case (even m) + then show ?case + by (cases n) + (auto simp add: bit_double_iff Parity.bit_double_iff dest: mult_not_zero) + next + case (odd m) + then show ?case + by (cases n) + (auto simp add: bit_double_iff even_bit_succ_iff Parity.bit_Suc dest: mult_not_zero) + qed + with False show ?thesis + by simp +qed + +end + instantiation int :: semiring_bits begin @@ -1453,6 +1504,27 @@ end +context semiring_bit_shifts +begin + +lemma push_bit_of_nat: + \push_bit n (of_nat m) = of_nat (push_bit n m)\ + by (simp add: push_bit_eq_mult semiring_bit_shifts_class.push_bit_eq_mult) + +lemma of_nat_push_bit: + \of_nat (push_bit m n) = push_bit m (of_nat n)\ + by (simp add: push_bit_eq_mult semiring_bit_shifts_class.push_bit_eq_mult) + +lemma take_bit_of_nat: + \take_bit n (of_nat m) = of_nat (take_bit n m)\ + by (rule bit_eqI) (simp add: bit_take_bit_iff Parity.bit_take_bit_iff bit_of_nat_iff) + +lemma of_nat_take_bit: + \of_nat (take_bit n m) = take_bit n (of_nat m)\ + by (rule bit_eqI) (simp add: bit_take_bit_iff Parity.bit_take_bit_iff bit_of_nat_iff) + +end + instantiation int :: semiring_bit_shifts begin @@ -1498,10 +1570,6 @@ "push_bit n a = 0 \ a = 0" by (simp add: push_bit_eq_mult) -lemma push_bit_of_nat: - "push_bit n (of_nat m) = of_nat (push_bit n m)" - by (simp add: push_bit_eq_mult Parity.push_bit_eq_mult) - lemma take_bit_add: "take_bit n (take_bit n a + take_bit n b) = take_bit n (a + b)" by (simp add: take_bit_eq_mod mod_simps) @@ -1534,10 +1602,6 @@ \take_bit (numeral l) (numeral (Num.Bit1 k)) = take_bit (pred_numeral l) (numeral k) * 2 + 1\ by (simp add: take_bit_rec numeral_Bit1_div_2 mod_2_eq_odd) -lemma take_bit_of_nat: - "take_bit n (of_nat m) = of_nat (take_bit n m)" - by (simp add: take_bit_eq_mod Parity.take_bit_eq_mod of_nat_mod [of m "2 ^ n"]) - lemma drop_bit_Suc_bit0 [simp]: \drop_bit (Suc n) (numeral (Num.Bit0 k)) = drop_bit n (numeral k)\ by (simp add: drop_bit_Suc numeral_Bit0_div_2) @@ -1569,18 +1633,10 @@ by (simp add: bit_iff_odd semiring_bits_class.bit_iff_odd) qed -lemma of_nat_push_bit: - \of_nat (push_bit m n) = push_bit m (of_nat n)\ - by (simp add: push_bit_eq_mult semiring_bit_shifts_class.push_bit_eq_mult) - lemma of_nat_drop_bit: \of_nat (drop_bit m n) = drop_bit m (of_nat n)\ by (simp add: drop_bit_eq_div semiring_bit_shifts_class.drop_bit_eq_div of_nat_div) -lemma of_nat_take_bit: - \of_nat (take_bit m n) = take_bit m (of_nat n)\ - by (simp add: take_bit_eq_mod semiring_bit_shifts_class.take_bit_eq_mod of_nat_mod) - lemma bit_push_bit_iff_of_nat_iff: \bit (push_bit m (of_nat r)) n \ m \ n \ bit (of_nat r) (n - m)\ by (auto simp add: bit_push_bit_iff) @@ -1591,9 +1647,9 @@ instance int :: unique_euclidean_semiring_with_bit_shifts .. -lemma bit_nat_iff [simp]: - \bit (nat k) n \ k > 0 \ bit k n\ -proof (cases \k > 0\) +lemma bit_nat_iff: + \bit (nat k) n \ k \ 0 \ bit k n\ +proof (cases \k \ 0\) case True moreover define m where \m = nat k\ ultimately have \k = int m\ @@ -1606,6 +1662,21 @@ by simp qed +lemma push_bit_nat_eq: + \push_bit n (nat k) = nat (push_bit n k)\ + by (cases \k \ 0\) (simp_all add: push_bit_eq_mult nat_mult_distrib not_le mult_nonneg_nonpos2) + +lemma drop_bit_nat_eq: + \drop_bit n (nat k) = nat (drop_bit n k)\ + apply (cases \k \ 0\) + apply (simp_all add: drop_bit_eq_div nat_div_distrib nat_power_eq not_le) + apply (simp add: divide_int_def) + done + +lemma take_bit_nat_eq: + \take_bit n (nat k) = nat (take_bit n k)\ if \k \ 0\ + using that by (simp add: take_bit_eq_mod nat_mod_distrib nat_power_eq) + lemma nat_take_bit_eq: \nat (take_bit n k) = take_bit n (nat k)\ if \k \ 0\ diff -r 5e26a4bca0c2 -r 0f3d24dc197f src/HOL/Word/Conversions.thy --- a/src/HOL/Word/Conversions.thy Sat Aug 29 16:30:33 2020 +0100 +++ b/src/HOL/Word/Conversions.thy Sun Aug 30 15:15:28 2020 +0000 @@ -13,7 +13,8 @@ hide_const (open) unat uint sint word_of_int ucast scast -subsection \Conversions to words\ + +subsection \Conversions to word\ abbreviation word_of_nat :: \nat \ 'a::len word\ where \word_of_nat \ of_nat\ @@ -57,81 +58,10 @@ \word_of_int k = (0 :: 'a::len word) \ 2 ^ LENGTH('a) dvd k\ using of_int_word_eq_iff [where ?'a = 'a, of k 0] by (simp add: take_bit_eq_0_iff) -lemma int_AND_eq: - \int (m AND n) = int m AND int n\ - by (rule bit_eqI) (simp add: bit_and_iff) - -lemma int_OR_eq: - \int (m OR n) = int m OR int n\ - by (rule bit_eqI) (simp add: bit_or_iff) - -lemma int_XOR_eq: - \int (m XOR n) = int m XOR int n\ - by (rule bit_eqI) (simp add: bit_xor_iff) - -context semiring_bit_operations -begin - -lemma push_bit_and [simp]: - \push_bit n (a AND b) = push_bit n a AND push_bit n b\ - by (rule bit_eqI) (auto simp add: bit_push_bit_iff bit_and_iff) - -lemma push_bit_or [simp]: - \push_bit n (a OR b) = push_bit n a OR push_bit n b\ - by (rule bit_eqI) (auto simp add: bit_push_bit_iff bit_or_iff) - -lemma push_bit_xor [simp]: - \push_bit n (a XOR b) = push_bit n a XOR push_bit n b\ - by (rule bit_eqI) (auto simp add: bit_push_bit_iff bit_xor_iff) - -lemma drop_bit_and [simp]: - \drop_bit n (a AND b) = drop_bit n a AND drop_bit n b\ - by (rule bit_eqI) (auto simp add: bit_drop_bit_eq bit_and_iff) - -lemma drop_bit_or [simp]: - \drop_bit n (a OR b) = drop_bit n a OR drop_bit n b\ - by (rule bit_eqI) (auto simp add: bit_drop_bit_eq bit_or_iff) -lemma drop_bit_xor [simp]: - \drop_bit n (a XOR b) = drop_bit n a XOR drop_bit n b\ - by (rule bit_eqI) (auto simp add: bit_drop_bit_eq bit_xor_iff) - -end - -lemma bit_word_of_nat_iff: - \bit (word_of_nat m :: 'a::len word) n \ n < LENGTH('a) \ bit m n\ - by transfer simp - -lemma bit_word_of_int_iff: - \bit (word_of_int k :: 'a::len word) n \ n < LENGTH('a) \ bit k n\ - by transfer simp - -lemma word_of_nat_AND_eq: - \word_of_nat (m AND n) = word_of_nat m AND word_of_nat n\ - by (rule bit_eqI) (auto simp add: bit_word_of_nat_iff bit_and_iff) +subsection \Conversion from word\ -lemma word_of_int_AND_eq: - \word_of_int (k AND l) = word_of_int k AND word_of_int l\ - by (rule bit_eqI) (auto simp add: bit_word_of_int_iff bit_and_iff) - -lemma word_of_nat_OR_eq: - \word_of_nat (m OR n) = word_of_nat m OR word_of_nat n\ - by (rule bit_eqI) (auto simp add: bit_word_of_nat_iff bit_or_iff) - -lemma word_of_int_OR_eq: - \word_of_int (k OR l) = word_of_int k OR word_of_int l\ - by (rule bit_eqI) (auto simp add: bit_word_of_int_iff bit_or_iff) - -lemma word_of_nat_XOR_eq: - \word_of_nat (m XOR n) = word_of_nat m XOR word_of_nat n\ - by (rule bit_eqI) (auto simp add: bit_word_of_nat_iff bit_xor_iff) - -lemma word_of_int_XOR_eq: - \word_of_int (k XOR l) = word_of_int k XOR word_of_int l\ - by (rule bit_eqI) (auto simp add: bit_word_of_int_iff bit_xor_iff) - - -subsection \Conversion from words\ +subsubsection \Generic unsigned conversion\ context semiring_1 begin @@ -163,6 +93,114 @@ end +context semiring_bits +begin + +lemma bit_unsigned_iff: + \bit (unsigned w) n \ 2 ^ n \ 0 \ bit w n\ + for w :: \'b::len word\ + by (transfer fixing: bit) (simp add: bit_of_nat_iff bit_nat_iff bit_take_bit_iff) + +end + +context semiring_bit_shifts +begin + +lemma unsigned_push_bit_eq: + \unsigned (push_bit n w) = take_bit LENGTH('b) (push_bit n (unsigned w))\ + for w :: \'b::len word\ +proof (rule bit_eqI) + fix m + assume \2 ^ m \ 0\ + show \bit (unsigned (push_bit n w)) m = bit (take_bit LENGTH('b) (push_bit n (unsigned w))) m\ + proof (cases \n \ 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 (simp add: bit_unsigned_iff bit_push_bit_iff Parity.bit_push_bit_iff bit_take_bit_iff ac_simps exp_eq_zero_iff not_le) + next + case False + then show ?thesis + by (simp add: not_le bit_unsigned_iff bit_push_bit_iff Parity.bit_push_bit_iff bit_take_bit_iff) + qed +qed + +lemma unsigned_take_bit_eq: + \unsigned (take_bit n w) = take_bit n (unsigned w)\ + for w :: \'b::len word\ + by (rule bit_eqI) (simp add: bit_unsigned_iff bit_take_bit_iff Parity.bit_take_bit_iff) + +end + +context semiring_bit_operations +begin + +lemma unsigned_and_eq: + \unsigned (v AND w) = unsigned v AND unsigned w\ + for v w :: \'b::len word\ + by (rule bit_eqI) (simp add: bit_unsigned_iff bit_and_iff Bit_Operations.bit_and_iff) + +lemma unsigned_or_eq: + \unsigned (v OR w) = unsigned v OR unsigned w\ + for v w :: \'b::len word\ + by (rule bit_eqI) (simp add: bit_unsigned_iff bit_or_iff Bit_Operations.bit_or_iff) + +lemma unsigned_xor_eq: + \unsigned (v XOR w) = unsigned v XOR unsigned w\ + for v w :: \'b::len word\ + by (rule bit_eqI) (simp add: bit_unsigned_iff bit_xor_iff Bit_Operations.bit_xor_iff) + +end + +context ring_bit_operations +begin + +lemma unsigned_not_eq: + \unsigned (NOT w) = take_bit LENGTH('b) (NOT (unsigned w))\ + for w :: \'b::len word\ + by (rule bit_eqI) + (simp add: bit_unsigned_iff bit_take_bit_iff bit_not_iff Bit_Operations.bit_not_iff exp_eq_zero_iff not_le) + +end + +lemma unsigned_of_nat [simp]: + \unsigned (word_of_nat n :: 'a::len word) = of_nat (take_bit LENGTH('a) n)\ + by transfer (simp add: nat_eq_iff take_bit_of_nat) + +lemma unsigned_of_int [simp]: + \unsigned (word_of_int n :: 'a::len word) = of_int (take_bit LENGTH('a) n)\ + by transfer (simp add: nat_eq_iff take_bit_of_nat) + +context unique_euclidean_semiring_numeral +begin + +lemma unsigned_greater_eq: + \0 \ unsigned w\ for w :: \'b::len word\ + by (transfer fixing: less_eq) simp + +lemma unsigned_less: + \unsigned w < 2 ^ LENGTH('b)\ for w :: \'b::len word\ + by (transfer fixing: less) (simp add: take_bit_int_less_exp) + +end + +context linordered_semidom +begin + +lemma word_less_eq_iff_unsigned: + "a \ b \ unsigned a \ unsigned b" + by (transfer fixing: less_eq) (simp add: nat_le_eq_zle) + +lemma word_less_iff_unsigned: + "a < b \ unsigned a < unsigned b" + by (transfer fixing: less) (auto dest: preorder_class.le_less_trans [OF take_bit_nonnegative]) + +end + + +subsubsection \Generic signed conversion\ + context ring_1 begin @@ -198,6 +236,99 @@ end +context ring_bit_operations +begin + +lemma bit_signed_iff: + \bit (signed w) n \ 2 ^ n \ 0 \ bit w (min (LENGTH('b) - Suc 0) n)\ + for w :: \'b::len word\ + by (transfer fixing: bit) (auto simp add: bit_of_int_iff 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))\ + for w :: \'b::len word\ +proof (rule bit_eqI) + fix m + assume \2 ^ m \ 0\ + define q where \q = LENGTH('b) - Suc 0\ + 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\) + 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) + 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) + qed +qed + +lemma signed_take_bit_eq: + \signed (take_bit n w) = (if n < LENGTH('b) then take_bit n (signed w) else signed w)\ + for w :: \'b::len word\ + by (transfer fixing: take_bit; cases \LENGTH('b)\) + (auto simp add: signed_take_bit_take_bit take_bit_signed_take_bit take_bit_of_int min_def) + +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))\ + for w :: \'b::len word\ +proof (rule bit_eqI) + fix n + assume \2 ^ n \ 0\ + 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\) + 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) + qed +qed + +lemma signed_and_eq: + \signed (v AND w) = signed v AND signed w\ + for v w :: \'b::len word\ + by (rule bit_eqI) (simp add: bit_signed_iff bit_and_iff Bit_Operations.bit_and_iff) + +lemma signed_or_eq: + \signed (v OR w) = signed v OR signed w\ + for v w :: \'b::len word\ + by (rule bit_eqI) (simp add: bit_signed_iff bit_or_iff Bit_Operations.bit_or_iff) + +lemma signed_xor_eq: + \signed (v XOR w) = signed v XOR signed w\ + for v w :: \'b::len word\ + by (rule bit_eqI) (simp add: bit_signed_iff bit_xor_iff Bit_Operations.bit_xor_iff) + +end + +lemma signed_of_nat [simp]: + \signed (word_of_nat n :: 'a::len word) = of_int (signed_take_bit (LENGTH('a) - Suc 0) (int n))\ + by transfer simp + +lemma signed_of_int [simp]: + \signed (word_of_int n :: 'a::len word) = of_int (signed_take_bit (LENGTH('a) - Suc 0) n)\ + by transfer simp + + +subsubsection \Important special cases\ + abbreviation unat :: \'a::len word \ nat\ where \unat \ unsigned\ @@ -257,10 +388,6 @@ end -lemma unsigned_of_nat [simp]: - \unsigned (of_nat n :: 'a::len word) = of_nat (take_bit LENGTH('a) n)\ - by transfer (simp add: nat_eq_iff take_bit_of_nat) - lemma of_nat_unat [simp]: \of_nat (unat w) = unsigned w\ by transfer simp @@ -269,40 +396,66 @@ \of_int (uint w) = unsigned w\ by transfer simp -context unique_euclidean_semiring_numeral -begin - -lemma unsigned_greater_eq: - \0 \ unsigned w\ for w :: \'b::len word\ - by (transfer fixing: less_eq) simp - -lemma unsigned_less: - \unsigned w < 2 ^ LENGTH('b)\ for w :: \'b::len word\ - by (transfer fixing: less) (simp add: take_bit_int_less_exp) - -end +lemma unat_div_distrib: + \unat (v div w) = unat v div unat w\ +proof transfer + fix k l + have \nat (take_bit LENGTH('a) k) div nat (take_bit LENGTH('a) l) \ nat (take_bit LENGTH('a) k)\ + by (rule div_le_dividend) + also have \nat (take_bit LENGTH('a) k) < 2 ^ LENGTH('a)\ + by (simp add: nat_less_iff take_bit_int_less_exp) + finally show \(nat \ take_bit LENGTH('a)) (take_bit LENGTH('a) k div take_bit LENGTH('a) l) = + (nat \ take_bit LENGTH('a)) k div (nat \ take_bit LENGTH('a)) l\ + by (simp add: nat_take_bit_eq div_int_pos_iff nat_div_distrib take_bit_eq_self) +qed -context linordered_semidom -begin - -lemma word_less_eq_iff_unsigned: - "a \ b \ unsigned a \ unsigned b" - by (transfer fixing: less_eq) (simp add: nat_le_eq_zle) +lemma unat_mod_distrib: + \unat (v mod w) = unat v mod unat w\ +proof transfer + fix k l + have \nat (take_bit LENGTH('a) k) mod nat (take_bit LENGTH('a) l) \ nat (take_bit LENGTH('a) k)\ + by (rule mod_less_eq_dividend) + also have \nat (take_bit LENGTH('a) k) < 2 ^ LENGTH('a)\ + by (simp add: nat_less_iff take_bit_int_less_exp) + finally show \(nat \ take_bit LENGTH('a)) (take_bit LENGTH('a) k mod take_bit LENGTH('a) l) = + (nat \ take_bit LENGTH('a)) k mod (nat \ take_bit LENGTH('a)) l\ + by (simp add: nat_take_bit_eq mod_int_pos_iff less_le nat_mod_distrib take_bit_eq_self) +qed -lemma word_less_iff_unsigned: - "a < b \ unsigned a < unsigned b" - by (transfer fixing: less) (auto dest: preorder_class.le_less_trans [OF take_bit_nonnegative]) +lemma uint_div_distrib: + \uint (v div w) = uint v div uint w\ +proof - + have \int (unat (v div w)) = int (unat v div unat w)\ + by (simp add: unat_div_distrib) + then show ?thesis + by (simp add: of_nat_div) +qed -end - -lemma signed_of_int [simp]: - \signed (word_of_int k :: 'a::len word) = of_int (signed_take_bit (LENGTH('a) - 1) k)\ - by transfer simp +lemma uint_mod_distrib: + \uint (v mod w) = uint v mod uint w\ +proof - + have \int (unat (v mod w)) = int (unat v mod unat w)\ + by (simp add: unat_mod_distrib) + then show ?thesis + by (simp add: of_nat_mod) +qed lemma of_int_sint [simp]: \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_unfold) + +lemma sint_push_bit_eq: + \signed (push_bit n w) = signed_take_bit (LENGTH('a) - 1) (push_bit n (signed w))\ + for w :: \'a::len word\ + by (transfer fixing: n; cases \LENGTH('a)\) + (auto simp add: signed_take_bit_def bit_concat_bit_iff bit_push_bit_iff bit_take_bit_iff bit_or_iff le_diff_conv2, + auto simp add: take_bit_push_bit not_less concat_bit_eq_iff take_bit_concat_bit_eq le_diff_conv2) + lemma sint_greater_eq: \- (2 ^ (LENGTH('a) - 1)) \ sint w\ for w :: \'a::len word\ proof (cases \bit w (LENGTH('a) - 1)\) @@ -320,6 +473,6 @@ lemma sint_less: \sint w < 2 ^ (LENGTH('a) - 1)\ for w :: \'a::len word\ by (cases \bit w (LENGTH('a) - 1)\; transfer) - (simp_all add: signed_take_bit_eq signed_take_bit_eq_or take_bit_int_less_exp not_eq_complement mask_eq_exp_minus_1 OR_upper) + (simp_all add: signed_take_bit_eq signed_take_bit_unfold take_bit_int_less_exp not_eq_complement mask_eq_exp_minus_1 OR_upper) end diff -r 5e26a4bca0c2 -r 0f3d24dc197f src/HOL/Word/Word.thy --- a/src/HOL/Word/Word.thy Sat Aug 29 16:30:33 2020 +0100 +++ b/src/HOL/Word/Word.thy Sun Aug 30 15:15:28 2020 +0000 @@ -931,9 +931,13 @@ \uint (take_bit n w) = take_bit n (uint w)\ by transfer (simp add: ac_simps) +lemma take_bit_word_eq_self: + \take_bit n w = w\ if \LENGTH('a) \ n\ for w :: \'a::len word\ + using that by transfer simp + lemma take_bit_length_eq [simp]: \take_bit LENGTH('a) w = w\ for w :: \'a::len word\ - by transfer simp + by (rule take_bit_word_eq_self) simp lemma bit_word_of_int_iff: \bit (word_of_int k :: 'a::len word) n \ n < LENGTH('a) \ bit k n\ @@ -3865,7 +3869,7 @@ apply (auto simp add: signed_take_bit_eq_take_bit_minus take_bit_Suc_from_most n not_less intro!: *) done then show ?thesis - apply (simp add: word_size shiftr_word_eq drop_bit_eq_zero_iff_not_bit_last bit_and_iff bit_xor_iff) + apply (simp only: One_nat_def word_size shiftr_word_eq drop_bit_eq_zero_iff_not_bit_last bit_and_iff bit_xor_iff) apply (simp add: bit_last_iff) done qed