# HG changeset patch # User haftmann # Date 1707937394 0 # Node ID ad29777e8746b6422f582ff15936a36c383a4fba # Parent 71731d28b86dfa267411a1bea5cf89700ebf61ac more on disjunctive addition/subtraction diff -r 71731d28b86d -r ad29777e8746 src/HOL/Bit_Operations.thy --- a/src/HOL/Bit_Operations.thy Wed Feb 14 17:00:47 2024 +0100 +++ b/src/HOL/Bit_Operations.thy Wed Feb 14 19:03:14 2024 +0000 @@ -327,40 +327,6 @@ \bit (a mod 2) n \ n = 0 \ odd a\ by (simp add: mod_2_eq_odd bit_simps) -lemma bit_disjunctive_add_iff: - \bit (a + b) n \ bit a n \ bit b n\ - if \\n. \ bit a n \ \ bit b n\ -proof (cases \possible_bit TYPE('a) n\) - case False - then show ?thesis - by (auto dest: impossible_bit) -next - case True - with that show ?thesis proof (induction n arbitrary: a b) - case 0 - from "0.prems"(1) [of 0] show ?case - by (auto simp add: bit_0) - next - case (Suc n) - from Suc.prems(1) [of 0] have even: \even a \ even b\ - by (auto simp add: bit_0) - have bit: \\ bit (a div 2) n \ \ bit (b div 2) n\ for n - using Suc.prems(1) [of \Suc n\] by (simp add: bit_Suc) - from Suc.prems(2) have \possible_bit TYPE('a) (Suc n)\ \possible_bit TYPE('a) n\ - by (simp_all add: possible_bit_less_imp) - have \a + b = (a div 2 * 2 + a mod 2) + (b div 2 * 2 + b mod 2)\ - using div_mult_mod_eq [of a 2] div_mult_mod_eq [of b 2] by simp - also have \\ = of_bool (odd a \ odd b) + 2 * (a div 2 + b div 2)\ - using even by (auto simp add: algebra_simps mod2_eq_if) - finally have \bit ((a + b) div 2) n \ bit (a div 2 + b div 2) n\ - using \possible_bit TYPE('a) (Suc n)\ by simp (simp_all flip: bit_Suc add: bit_double_iff possible_bit_def) - also have \\ \ bit (a div 2) n \ bit (b div 2) n\ - using bit \possible_bit TYPE('a) n\ by (rule Suc.IH) - finally show ?case - by (simp add: bit_Suc) - qed -qed - end lemma nat_bit_induct [case_names zero even odd]: @@ -723,10 +689,6 @@ \even (a OR b) \ even a \ even b\ using bit_or_iff [of a b 0] by (auto simp add: bit_0) -lemma disjunctive_add: - \a + b = a OR b\ if \\n. \ bit a n \ \ bit b n\ - by (rule bit_eqI) (use that in \simp add: bit_disjunctive_add_iff bit_or_iff\) - lemma even_xor_iff: \even (a XOR b) \ (even a \ even b)\ using bit_xor_iff [of a b 0] by (auto simp add: bit_0) @@ -1283,13 +1245,59 @@ \take_bit n a = (\k = 0.. by (simp flip: horner_sum_bit_eq_take_bit add: horner_sum_eq_sum push_bit_eq_mult) +lemma disjunctive_xor_eq_or: + \a XOR b = a OR b\ if \a AND b = 0\ + using that by (auto simp add: bit_eq_iff bit_simps) + +lemma disjunctive_add_eq_or: + \a + b = a OR b\ if \a AND b = 0\ +proof (rule bit_eqI) + fix n + assume \possible_bit TYPE('a) n\ + moreover from that have \\n. \ bit (a AND b) n\ + by simp + then have \\n. \ bit a n \ \ bit b n\ + by (simp add: bit_simps) + ultimately show \bit (a + b) n \ bit (a OR b) n\ + proof (induction n arbitrary: a b) + case 0 + from "0"(2)[of 0] show ?case + by (auto simp add: even_or_iff bit_0) + next + case (Suc n) + from Suc.prems(2) [of 0] have even: \even a \ even b\ + by (auto simp add: bit_0) + have bit: \\ bit (a div 2) n \ \ bit (b div 2) n\ for n + using Suc.prems(2) [of \Suc n\] by (simp add: bit_Suc) + from Suc.prems have \possible_bit TYPE('a) n\ + using possible_bit_less_imp by force + with \\n. \ bit (a div 2) n \ \ bit (b div 2) n\ Suc.IH [of \a div 2\ \b div 2\] + have IH: \bit (a div 2 + b div 2) n \ bit (a div 2 OR b div 2) n\ + by (simp add: bit_Suc) + have \a + b = (a div 2 * 2 + a mod 2) + (b div 2 * 2 + b mod 2)\ + using div_mult_mod_eq [of a 2] div_mult_mod_eq [of b 2] by simp + also have \\ = of_bool (odd a \ odd b) + 2 * (a div 2 + b div 2)\ + using even by (auto simp add: algebra_simps mod2_eq_if) + finally have \bit ((a + b) div 2) n \ bit (a div 2 + b div 2) n\ + using \possible_bit TYPE('a) (Suc n)\ by simp (simp_all flip: bit_Suc add: bit_double_iff possible_bit_def) + also have \\ \ bit (a div 2 OR b div 2) n\ + by (rule IH) + finally show ?case + by (simp add: bit_simps flip: bit_Suc) + qed +qed + +lemma disjunctive_add_eq_xor: + \a + b = a XOR b\ if \a AND b = 0\ + using that by (simp add: disjunctive_add_eq_or disjunctive_xor_eq_or) + lemma set_bit_eq: \set_bit n a = a + of_bool (\ bit a n) * 2 ^ n\ proof - - have \set_bit n a = a OR of_bool (\ bit a n) * 2 ^ n\ - by (rule bit_eqI) (auto simp add: bit_simps) + have \a AND of_bool (\ bit a n) * 2 ^ n = 0\ + by (auto simp add: bit_eq_iff bit_simps) then show ?thesis - by (subst disjunctive_add) (auto simp add: bit_simps) + by (auto simp add: bit_eq_iff bit_simps disjunctive_add_eq_or) qed end @@ -1417,17 +1425,25 @@ \a AND b = - 1 \ a = - 1 \ b = - 1\ by (auto simp: bit_eq_iff bit_simps) -lemma disjunctive_diff: - \a - b = a AND NOT b\ if \\n. bit b n \ bit a n\ +lemma disjunctive_and_not_eq_xor: + \a AND NOT b = a XOR b\ if \NOT a AND b = 0\ + using that by (auto simp add: bit_eq_iff bit_simps) + +lemma disjunctive_diff_eq_and_not: + \a - b = a AND NOT b\ if \NOT a AND b = 0\ proof - - have \NOT a + b = NOT a OR b\ - by (rule disjunctive_add) (auto simp add: bit_not_iff dest: that) + from that have \NOT a + b = NOT a OR b\ + by (rule disjunctive_add_eq_or) then have \NOT (NOT a + b) = NOT (NOT a OR b)\ by simp then show ?thesis by (simp add: not_add_distrib) qed +lemma disjunctive_diff_eq_xor: + \a AND NOT b = a XOR b\ if \NOT a AND b = 0\ + using that by (simp add: disjunctive_and_not_eq_xor disjunctive_diff_eq_and_not) + lemma push_bit_minus: \push_bit n (- a) = - push_bit n a\ by (simp add: push_bit_eq_mult) @@ -1443,15 +1459,12 @@ lemma take_bit_not_eq_mask_diff: \take_bit n (NOT a) = mask n - take_bit n a\ proof - - have \take_bit n (NOT a) = take_bit n (NOT (take_bit n a))\ - by (simp add: take_bit_not_take_bit) - also have \\ = mask n AND NOT (take_bit n a)\ - by (simp add: take_bit_eq_mask ac_simps) - also have \\ = mask n - take_bit n a\ - by (subst disjunctive_diff) - (auto simp add: bit_take_bit_iff bit_mask_iff bit_imp_possible_bit) - finally show ?thesis - by simp + have \NOT (mask n) AND take_bit n a = 0\ + by (simp add: bit_eq_iff bit_simps) + moreover have \take_bit n (NOT a) = mask n AND NOT (take_bit n a)\ + by (auto simp add: bit_eq_iff bit_simps) + ultimately show ?thesis + by (simp add: disjunctive_diff_eq_and_not) qed lemma mask_eq_take_bit_minus_one: @@ -1512,10 +1525,12 @@ lemma unset_bit_eq: \unset_bit n a = a - of_bool (bit a n) * 2 ^ n\ proof - - have \unset_bit n a = a AND NOT (of_bool (bit a n) * 2 ^ n)\ - by (rule bit_eqI) (auto simp add: bit_simps) - then show ?thesis - by (subst disjunctive_diff) (auto simp add: bit_simps simp flip: push_bit_eq_mult) + have \NOT a AND of_bool (bit a n) * 2 ^ n = 0\ + by (auto simp add: bit_eq_iff bit_simps) + moreover have \unset_bit n a = a AND NOT (of_bool (bit a n) * 2 ^ n)\ + by (auto simp add: bit_eq_iff bit_simps) + ultimately show ?thesis + by (simp add: disjunctive_diff_eq_and_not) qed end @@ -3327,8 +3342,12 @@ lemma concat_bit_eq: \concat_bit n k l = take_bit n k + push_bit n l\ - by (simp add: concat_bit_def take_bit_eq_mask - bit_and_iff bit_mask_iff bit_push_bit_iff disjunctive_add) +proof - + have \take_bit n k AND push_bit n l = 0\ + by (simp add: bit_eq_iff bit_simps) + then show ?thesis + by (simp add: bit_eq_iff bit_simps disjunctive_add_eq_or) +qed lemma concat_bit_0 [simp]: \concat_bit 0 k l = l\ @@ -3479,6 +3498,26 @@ using that by (rule le_SucE; intro bit_eqI) (auto simp add: bit_take_bit_iff bit_signed_take_bit_iff min_def less_Suc_eq) +lemma signed_take_bit_eq_take_bit_add: + \signed_take_bit n k = take_bit (Suc n) k + NOT (mask (Suc n)) * of_bool (bit k n)\ +proof (cases \bit k n\) + case False + show ?thesis + by (rule bit_eqI) (simp add: False bit_simps min_def less_Suc_eq) +next + case True + have \signed_take_bit n k = take_bit (Suc n) k OR NOT (mask (Suc n))\ + by (rule bit_eqI) (auto simp add: bit_signed_take_bit_iff min_def bit_take_bit_iff bit_or_iff bit_not_iff bit_mask_iff less_Suc_eq True) + also have \\ = take_bit (Suc n) k + NOT (mask (Suc n))\ + by (simp add: disjunctive_add_eq_or bit_eq_iff bit_simps) + finally show ?thesis + by (simp add: True) +qed + +lemma signed_take_bit_eq_take_bit_minus: + \signed_take_bit n k = take_bit (Suc n) k - 2 ^ Suc n * of_bool (bit k n)\ + by (simp add: signed_take_bit_eq_take_bit_add flip: minus_exp_eq_not_mask) + end text \Modulus centered around 0\ @@ -3538,34 +3577,18 @@ by (simp only: signed_take_bit_eq_iff_take_bit_eq take_bit_mult) qed -lemma signed_take_bit_eq_take_bit_minus: - \signed_take_bit n k = take_bit (Suc n) k - 2 ^ Suc n * of_bool (bit k n)\ - for k :: int -proof (cases \bit k n\) - case True - have \signed_take_bit n k = take_bit (Suc n) k OR NOT (mask (Suc n))\ - by (rule bit_eqI) (auto simp add: bit_signed_take_bit_iff min_def bit_take_bit_iff bit_or_iff bit_not_iff bit_mask_iff less_Suc_eq True) - then have \signed_take_bit n k = take_bit (Suc n) k + NOT (mask (Suc n))\ - by (simp add: disjunctive_add bit_take_bit_iff bit_not_iff bit_mask_iff) - with True show ?thesis - by (simp flip: minus_exp_eq_not_mask) -next - case False - show ?thesis - by (rule bit_eqI) (simp add: False bit_signed_take_bit_iff bit_take_bit_iff min_def less_Suc_eq) -qed - lemma signed_take_bit_eq_take_bit_shift: - \signed_take_bit n k = take_bit (Suc n) (k + 2 ^ n) - 2 ^ n\ + \signed_take_bit n k = take_bit (Suc n) (k + 2 ^ n) - 2 ^ n\ (is \?lhs = ?rhs\) for k :: int proof - - have *: \take_bit n k OR 2 ^ n = take_bit n k + 2 ^ n\ - by (simp add: disjunctive_add bit_exp_iff bit_take_bit_iff) + have \take_bit n k AND 2 ^ n = 0\ + by (rule bit_eqI) (simp add: bit_simps) + then have *: \take_bit n k OR 2 ^ n = take_bit n k + 2 ^ n\ + by (simp add: disjunctive_add_eq_or) have \take_bit n k - 2 ^ n = take_bit n k + NOT (mask n)\ by (simp add: minus_exp_eq_not_mask) also have \\ = take_bit n k OR NOT (mask n)\ - by (rule disjunctive_add) - (simp add: bit_exp_iff bit_take_bit_iff bit_not_iff bit_mask_iff) + by (rule disjunctive_add_eq_or) (simp add: bit_eq_iff bit_simps) finally have **: \take_bit n k - 2 ^ n = take_bit n k OR NOT (mask n)\ . have \take_bit (Suc n) (k + 2 ^ n) = take_bit (Suc n) (take_bit (Suc n) k + take_bit (Suc n) (2 ^ n))\ by (simp only: take_bit_add) @@ -3574,8 +3597,7 @@ finally have \take_bit (Suc n) (k + 2 ^ n) = take_bit (Suc n) (2 ^ (n + of_bool (bit k n)) + take_bit n k)\ by (simp add: ac_simps) also have \2 ^ (n + of_bool (bit k n)) + take_bit n k = 2 ^ (n + of_bool (bit k n)) OR take_bit n k\ - by (rule disjunctive_add) - (auto simp add: disjunctive_add bit_take_bit_iff bit_double_iff bit_exp_iff) + by (rule disjunctive_add_eq_or, rule bit_eqI) (simp add: bit_simps) finally show ?thesis using * ** by (simp add: signed_take_bit_def concat_bit_Suc min_def ac_simps) qed @@ -3681,16 +3703,7 @@ \signed_take_bit n a = (let l = take_bit (Suc n) a in if bit l n then l + push_bit (Suc n) (- 1) else l)\ -proof - - have *: \take_bit (Suc n) a + push_bit n (- 2) = - take_bit (Suc n) a OR NOT (mask (Suc n))\ - by (auto simp add: bit_take_bit_iff bit_push_bit_iff bit_not_iff bit_mask_iff disjunctive_add - simp flip: push_bit_minus_one_eq_not_mask) - show ?thesis - by (rule bit_eqI) - (auto simp add: Let_def * bit_signed_take_bit_iff bit_take_bit_iff min_def less_Suc_eq bit_not_iff - bit_mask_iff bit_or_iff simp del: push_bit_minus_one_eq_not_mask) -qed + by (simp add: signed_take_bit_eq_take_bit_add bit_simps) subsection \Key ideas of bit operations\ @@ -3833,6 +3846,40 @@ \\ bit a n\ if \2 ^ n = 0\ using that by (simp add: bit_iff_odd) +lemma bit_disjunctive_add_iff [no_atp]: + \bit (a + b) n \ bit a n \ bit b n\ + if \\n. \ bit a n \ \ bit b n\ +proof (cases \possible_bit TYPE('a) n\) + case False + then show ?thesis + by (auto dest: impossible_bit) +next + case True + with that show ?thesis proof (induction n arbitrary: a b) + case 0 + from "0.prems"(1) [of 0] show ?case + by (auto simp add: bit_0) + next + case (Suc n) + from Suc.prems(1) [of 0] have even: \even a \ even b\ + by (auto simp add: bit_0) + have bit: \\ bit (a div 2) n \ \ bit (b div 2) n\ for n + using Suc.prems(1) [of \Suc n\] by (simp add: bit_Suc) + from Suc.prems(2) have \possible_bit TYPE('a) (Suc n)\ \possible_bit TYPE('a) n\ + by (simp_all add: possible_bit_less_imp) + have \a + b = (a div 2 * 2 + a mod 2) + (b div 2 * 2 + b mod 2)\ + using div_mult_mod_eq [of a 2] div_mult_mod_eq [of b 2] by simp + also have \\ = of_bool (odd a \ odd b) + 2 * (a div 2 + b div 2)\ + using even by (auto simp add: algebra_simps mod2_eq_if) + finally have \bit ((a + b) div 2) n \ bit (a div 2 + b div 2) n\ + using \possible_bit TYPE('a) (Suc n)\ by simp (simp_all flip: bit_Suc add: bit_double_iff possible_bit_def) + also have \\ \ bit (a div 2) n \ bit (b div 2) n\ + using bit \possible_bit TYPE('a) n\ by (rule Suc.IH) + finally show ?case + by (simp add: bit_Suc) + qed +qed + end context semiring_bit_operations @@ -3870,6 +3917,26 @@ lemmas flip_bit_def [no_atp] = flip_bit_eq_xor +lemma disjunctive_add [no_atp]: + \a + b = a OR b\ if \\n. \ bit a n \ \ bit b n\ + by (rule disjunctive_add_eq_or) (use that in \simp add: bit_eq_iff bit_simps\) + +end + +context ring_bit_operations +begin + +lemma disjunctive_diff [no_atp]: + \a - b = a AND NOT b\ if \\n. bit b n \ bit a n\ +proof - + have \NOT a + b = NOT a OR b\ + by (rule disjunctive_add) (auto simp add: bit_not_iff dest: that) + then have \NOT (NOT a + b) = NOT (NOT a OR b)\ + by simp + then show ?thesis + by (simp add: not_add_distrib) +qed + end lemma and_nat_rec [no_atp]: