# HG changeset patch # User haftmann # Date 1594448462 0 # Node ID febdd4eead565d58a03512a2f2e1b861beafe838 # Parent 7a53fc156c2b6d3108bc9a8f8a809a83ac3eacc3 more on single-bit operations diff -r 7a53fc156c2b -r febdd4eead56 src/HOL/Library/Bit_Operations.thy --- a/src/HOL/Library/Bit_Operations.thy Fri Jul 10 22:38:03 2020 +0200 +++ b/src/HOL/Library/Bit_Operations.thy Sat Jul 11 06:21:02 2020 +0000 @@ -213,6 +213,14 @@ \a OR b = NOT (NOT a AND NOT b)\ by simp +lemma not_add_distrib: + \NOT (a + b) = NOT a - b\ + by (simp add: not_eq_complement algebra_simps) + +lemma not_diff_distrib: + \NOT (a - b) = NOT a + b\ + using not_add_distrib [of a \- b\] by simp + lemma push_bit_minus: \push_bit n (- a) = - push_bit n a\ by (simp add: push_bit_eq_mult) @@ -380,16 +388,20 @@ qed qed +lemma flip_bit_eq_if: + \flip_bit n a = (if bit a n then unset_bit else set_bit) n a\ + by (rule bit_eqI) (auto simp add: bit_set_bit_iff bit_unset_bit_iff bit_flip_bit_iff) + lemma take_bit_set_bit_eq: - \take_bit n (set_bit m w) = (if n \ m then take_bit n w else set_bit m (take_bit n w))\ + \take_bit n (set_bit m a) = (if n \ m then take_bit n a else set_bit m (take_bit n a))\ by (rule bit_eqI) (auto simp add: bit_take_bit_iff bit_set_bit_iff) lemma take_bit_unset_bit_eq: - \take_bit n (unset_bit m w) = (if n \ m then take_bit n w else unset_bit m (take_bit n w))\ + \take_bit n (unset_bit m a) = (if n \ m then take_bit n a else unset_bit m (take_bit n a))\ by (rule bit_eqI) (auto simp add: bit_take_bit_iff bit_unset_bit_iff) lemma take_bit_flip_bit_eq: - \take_bit n (flip_bit m w) = (if n \ m then take_bit n w else flip_bit m (take_bit n w))\ + \take_bit n (flip_bit m a) = (if n \ m then take_bit n a else flip_bit m (take_bit n a))\ by (rule bit_eqI) (auto simp add: bit_take_bit_iff bit_flip_bit_iff) end @@ -501,6 +513,41 @@ end +lemma disjunctive_add: + \k + l = k OR l\ if \\n. \ bit k n \ \ bit l n\ for k l :: int + \ \TODO: may integrate (indirectly) into \<^class>\semiring_bits\ premises\ +proof (rule bit_eqI) + fix n + from that have \bit (k + l) n \ bit k n \ bit l n\ + proof (induction n arbitrary: k l) + case 0 + from this [of 0] show ?case + by auto + next + case (Suc n) + have \bit ((k + l) div 2) n \ bit (k div 2 + l div 2) n\ + using Suc.prems [of 0] div_add1_eq [of k l] by auto + also have \bit (k div 2 + l div 2) n \ bit (k div 2) n \ bit (l div 2) n\ + by (rule Suc.IH) (use Suc.prems in \simp flip: bit_Suc\) + finally show ?case + by (simp add: bit_Suc) + qed + also have \\ \ bit (k OR l) n\ + by (simp add: bit_or_iff) + finally show \bit (k + l) n \ bit (k OR l) n\ . +qed + +lemma disjunctive_diff: + \k - l = k AND NOT l\ if \\n. bit l n \ bit k n\ for k l :: int +proof - + have \NOT k + l = NOT k OR l\ + by (rule disjunctive_add) (auto simp add: bit_not_iff dest: that) + then have \NOT (NOT k + l) = NOT (NOT k OR l)\ + by simp + then show ?thesis + by (simp add: not_add_distrib) +qed + lemma not_nonnegative_int_iff [simp]: \NOT k \ 0 \ k < 0\ for k :: int by (simp add: not_int_def) @@ -538,6 +585,28 @@ \k AND l < 0 \ k < 0 \ l < 0\ for k l :: int by (subst Not_eq_iff [symmetric]) (simp add: not_less) +lemma and_less_eq: + \k AND l \ k\ if \l < 0\ for k l :: int +using that proof (induction k arbitrary: l rule: int_bit_induct) + case zero + then show ?case + by simp +next + case minus + then show ?case + by simp +next + case (even k) + from even.IH [of \l div 2\] even.hyps even.prems + show ?case + by (simp add: and_int_rec [of _ l]) +next + case (odd k) + from odd.IH [of \l div 2\] odd.hyps odd.prems + show ?case + by (simp add: and_int_rec [of _ l]) +qed + lemma or_nonnegative_int_iff [simp]: \k OR l \ 0 \ k \ 0 \ l \ 0\ for k l :: int by (simp only: or_eq_not_not_and not_nonnegative_int_iff) simp @@ -546,6 +615,28 @@ \k OR l < 0 \ k < 0 \ l < 0\ for k l :: int by (subst Not_eq_iff [symmetric]) (simp add: not_less) +lemma or_greater_eq: + \k OR l \ k\ if \l \ 0\ for k l :: int +using that proof (induction k arbitrary: l rule: int_bit_induct) + case zero + then show ?case + by simp +next + case minus + then show ?case + by simp +next + case (even k) + from even.IH [of \l div 2\] even.hyps even.prems + show ?case + by (simp add: or_int_rec [of _ l]) +next + case (odd k) + from odd.IH [of \l div 2\] odd.hyps odd.prems + show ?case + by (simp add: or_int_rec [of _ l]) +qed + lemma xor_nonnegative_int_iff [simp]: \k XOR l \ 0 \ (k \ 0 \ l \ 0)\ for k l :: int by (simp only: bit.xor_def or_nonnegative_int_iff) auto @@ -578,50 +669,6 @@ \flip_bit n k < 0 \ k < 0\ for k :: int by (simp add: flip_bit_def) -lemma and_less_eq: - \k AND l \ k\ if \l < 0\ for k l :: int -using that proof (induction k arbitrary: l rule: int_bit_induct) - case zero - then show ?case - by simp -next - case minus - then show ?case - by simp -next - case (even k) - from even.IH [of \l div 2\] even.hyps even.prems - show ?case - by (simp add: and_int_rec [of _ l]) -next - case (odd k) - from odd.IH [of \l div 2\] odd.hyps odd.prems - show ?case - by (simp add: and_int_rec [of _ l]) -qed - -lemma or_greater_eq: - \k OR l \ k\ if \l \ 0\ for k l :: int -using that proof (induction k arbitrary: l rule: int_bit_induct) - case zero - then show ?case - by simp -next - case minus - then show ?case - by simp -next - case (even k) - from even.IH [of \l div 2\] even.hyps even.prems - show ?case - by (simp add: or_int_rec [of _ l]) -next - case (odd k) - from odd.IH [of \l div 2\] odd.hyps odd.prems - show ?case - by (simp add: or_int_rec [of _ l]) -qed - lemma set_bit_greater_eq: \set_bit n k \ k\ for k :: int by (simp add: set_bit_def or_greater_eq) @@ -630,6 +677,52 @@ \unset_bit n k \ k\ for k :: int by (simp add: unset_bit_def and_less_eq) +lemma set_bit_eq: + \set_bit n k = k + of_bool (\ bit k n) * 2 ^ n\ for k :: int +proof (rule bit_eqI) + fix m + show \bit (set_bit n k) m \ bit (k + of_bool (\ bit k n) * 2 ^ n) m\ + proof (cases \m = n\) + case True + then show ?thesis + apply (simp add: bit_set_bit_iff) + apply (simp add: bit_iff_odd div_plus_div_distrib_dvd_right) + done + next + case False + then show ?thesis + apply (clarsimp simp add: bit_set_bit_iff) + apply (subst disjunctive_add) + apply (clarsimp simp add: bit_exp_iff) + apply (clarsimp simp add: bit_or_iff bit_exp_iff) + done + qed +qed + +lemma unset_bit_eq: + \unset_bit n k = k - of_bool (bit k n) * 2 ^ n\ for k :: int +proof (rule bit_eqI) + fix m + show \bit (unset_bit n k) m \ bit (k - of_bool (bit k n) * 2 ^ n) m\ + proof (cases \m = n\) + case True + then show ?thesis + apply (simp add: bit_unset_bit_iff) + apply (simp add: bit_iff_odd) + using div_plus_div_distrib_dvd_right [of \2 ^ n\ \- (2 ^ n)\ k] + apply (simp add: dvd_neg_div) + done + next + case False + then show ?thesis + apply (clarsimp simp add: bit_unset_bit_iff) + apply (subst disjunctive_diff) + apply (clarsimp simp add: bit_exp_iff) + apply (clarsimp simp add: bit_and_iff bit_not_iff bit_exp_iff) + done + qed +qed + subsection \Instance \<^typ>\nat\\ diff -r 7a53fc156c2b -r febdd4eead56 src/HOL/Word/Word.thy --- a/src/HOL/Word/Word.thy Fri Jul 10 22:38:03 2020 +0200 +++ b/src/HOL/Word/Word.thy Sat Jul 11 06:21:02 2020 +0000 @@ -919,6 +919,24 @@ end +context + includes lifting_syntax +begin + +lemma set_bit_word_transfer: + \((=) ===> pcr_word ===> pcr_word) set_bit set_bit\ + by (unfold set_bit_def) transfer_prover + +lemma unset_bit_word_transfer: + \((=) ===> pcr_word ===> pcr_word) unset_bit unset_bit\ + by (unfold unset_bit_def) transfer_prover + +lemma flip_bit_word_transfer: + \((=) ===> pcr_word ===> pcr_word) flip_bit flip_bit\ + by (unfold flip_bit_def) transfer_prover + +end + instantiation word :: (len) semiring_bit_syntax begin