diff -r a0ab0dc28d3c -r 3c587b7c3d5c src/HOL/Bit_Operations.thy --- a/src/HOL/Bit_Operations.thy Tue Oct 26 16:22:03 2021 +0100 +++ b/src/HOL/Bit_Operations.thy Tue Oct 26 14:43:59 2021 +0000 @@ -542,10 +542,6 @@ \bit (of_bool b) n \ b \ n = 0\ by (simp add: bit_1_iff) -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_simps]: \bit (of_nat m) n \ possible_bit TYPE('a) n \ bit m n\ proof (cases \(2::'a) ^ n = 0\) @@ -831,7 +827,7 @@ "push_bit n 0 = 0" by (simp add: push_bit_eq_mult) -lemma push_bit_of_1: +lemma push_bit_of_1 [simp]: "push_bit n 1 = 2 ^ n" by (simp add: push_bit_eq_mult) @@ -1129,7 +1125,7 @@ \mask (numeral n) = 1 + 2 * mask (pred_numeral n)\ by (simp add: numeral_eq_Suc mask_Suc_double one_or_eq ac_simps) -lemma take_bit_mask [simp]: +lemma take_bit_of_mask [simp]: \take_bit m (mask n) = mask (min m n)\ by (rule bit_eqI) (simp add: bit_simps) @@ -1152,7 +1148,7 @@ lemma bit_iff_and_push_bit_not_eq_0: \bit a n \ a AND push_bit n 1 \ 0\ apply (cases \2 ^ n = 0\) - apply (simp_all add: push_bit_of_1 bit_eq_iff bit_and_iff bit_push_bit_iff exp_eq_0_imp_not_bit) + apply (simp_all add: bit_eq_iff bit_and_iff bit_push_bit_iff exp_eq_0_imp_not_bit) apply (simp_all add: bit_exp_iff) done @@ -1160,7 +1156,7 @@ lemma bit_set_bit_iff [bit_simps]: \bit (set_bit m a) n \ bit a n \ (m = n \ possible_bit TYPE('a) n)\ - by (auto simp add: set_bit_def push_bit_of_1 bit_or_iff bit_exp_iff) + by (auto simp add: set_bit_def bit_or_iff bit_exp_iff) lemma even_set_bit_iff: \even (set_bit m a) \ even a \ m \ 0\ @@ -1246,6 +1242,10 @@ \push_bit (Suc n) (numeral k) = push_bit n (numeral (Num.Bit0 k))\ by (simp add: numeral_eq_Suc mult_2_right) (simp add: numeral_Bit0) +lemma mask_eq_0_iff [simp]: + \mask n = 0 \ n = 0\ + by (cases n) (simp_all add: mask_Suc_double or_eq_0_iff) + end class ring_bit_operations = semiring_bit_operations + ring_parity + @@ -1379,7 +1379,7 @@ \mask n = take_bit n (- 1)\ by (simp add: bit_eq_iff bit_mask_iff bit_take_bit_iff conj_commute) -lemma take_bit_minus_one_eq_mask: +lemma take_bit_minus_one_eq_mask [simp]: \take_bit n (- 1) = mask n\ by (simp add: mask_eq_take_bit_minus_one) @@ -1387,7 +1387,7 @@ \- (2 ^ n) = NOT (mask n)\ by (rule bit_eqI) (simp add: bit_minus_iff bit_not_iff flip: mask_eq_exp_minus_1) -lemma push_bit_minus_one_eq_not_mask: +lemma push_bit_minus_one_eq_not_mask [simp]: \push_bit n (- 1) = NOT (mask n)\ by (simp add: push_bit_eq_mult minus_exp_eq_not_mask) @@ -1412,13 +1412,30 @@ \push_bit (numeral l) (- numeral k) = push_bit (pred_numeral l) (- numeral (Num.Bit0 k))\ by (simp only: numeral_eq_Suc push_bit_Suc_minus_numeral) -lemma take_bit_Suc_1: +lemma take_bit_Suc_minus_1_eq: \take_bit (Suc n) (- 1) = 2 ^ Suc n - 1\ - by (simp add: take_bit_minus_one_eq_mask mask_eq_exp_minus_1) - -lemma take_bit_numeral_1 [simp]: + by (simp add: mask_eq_exp_minus_1) + +lemma take_bit_numeral_minus_1_eq: \take_bit (numeral k) (- 1) = 2 ^ numeral k - 1\ - by (simp add: take_bit_minus_one_eq_mask mask_eq_exp_minus_1) + by (simp add: mask_eq_exp_minus_1) + +lemma push_bit_mask_eq: + \push_bit m (mask n) = mask (n + m) AND NOT (mask m)\ + apply (rule bit_eqI) + apply (auto simp add: bit_simps not_less possible_bit_def) + apply (drule sym [of 0]) + apply (simp only:) + using exp_not_zero_imp_exp_diff_not_zero apply (blast dest: exp_not_zero_imp_exp_diff_not_zero) + done + +lemma slice_eq_mask: + \push_bit n (take_bit m (drop_bit n a)) = a AND mask (m + n) AND NOT (mask n)\ + by (rule bit_eqI) (auto simp add: bit_simps) + +lemma push_bit_numeral_minus_1 [simp]: + \push_bit (numeral n) (- 1) = - (2 ^ numeral n)\ + by (simp add: push_bit_eq_mult) end @@ -2041,6 +2058,293 @@ for k :: int by (simp add: bit_simps) +lemma take_bit_incr_eq: + \take_bit n (k + 1) = 1 + take_bit n k\ if \take_bit n k \ 2 ^ n - 1\ + for k :: int +proof - + from that have \2 ^ n \ k mod 2 ^ n + 1\ + by (simp add: take_bit_eq_mod) + moreover have \k mod 2 ^ n < 2 ^ n\ + by simp + ultimately have *: \k mod 2 ^ n + 1 < 2 ^ n\ + by linarith + have \(k + 1) mod 2 ^ n = (k mod 2 ^ n + 1) mod 2 ^ n\ + by (simp add: mod_simps) + also have \\ = k mod 2 ^ n + 1\ + using * by (simp add: zmod_trivial_iff) + finally have \(k + 1) mod 2 ^ n = k mod 2 ^ n + 1\ . + then show ?thesis + by (simp add: take_bit_eq_mod) +qed + +lemma take_bit_decr_eq: + \take_bit n (k - 1) = take_bit n k - 1\ if \take_bit n k \ 0\ + for k :: int +proof - + from that have \k mod 2 ^ n \ 0\ + by (simp add: take_bit_eq_mod) + moreover have \k mod 2 ^ n \ 0\ \k mod 2 ^ n < 2 ^ n\ + by simp_all + ultimately have *: \k mod 2 ^ n > 0\ + by linarith + have \(k - 1) mod 2 ^ n = (k mod 2 ^ n - 1) mod 2 ^ n\ + by (simp add: mod_simps) + also have \\ = k mod 2 ^ n - 1\ + by (simp add: zmod_trivial_iff) + (use \k mod 2 ^ n < 2 ^ n\ * in linarith) + finally have \(k - 1) mod 2 ^ n = k mod 2 ^ n - 1\ . + then show ?thesis + by (simp add: take_bit_eq_mod) +qed + +lemma take_bit_int_greater_eq: + \k + 2 ^ n \ take_bit n k\ if \k < 0\ for k :: int +proof - + have \k + 2 ^ n \ take_bit n (k + 2 ^ n)\ + proof (cases \k > - (2 ^ n)\) + case False + then have \k + 2 ^ n \ 0\ + by simp + also note take_bit_nonnegative + finally show ?thesis . + next + case True + with that have \0 \ k + 2 ^ n\ and \k + 2 ^ n < 2 ^ n\ + by simp_all + then show ?thesis + by (simp only: take_bit_eq_mod mod_pos_pos_trivial) + qed + then show ?thesis + by (simp add: take_bit_eq_mod) +qed + +lemma take_bit_int_less_eq: + \take_bit n k \ k - 2 ^ n\ if \2 ^ n \ k\ and \n > 0\ for k :: int + using that zmod_le_nonneg_dividend [of \k - 2 ^ n\ \2 ^ n\] + by (simp add: take_bit_eq_mod) + +lemma take_bit_int_less_eq_self_iff: + \take_bit n k \ k \ 0 \ k\ (is \?P \ ?Q\) + for k :: int +proof + assume ?P + show ?Q + proof (rule ccontr) + assume \\ 0 \ k\ + then have \k < 0\ + by simp + with \?P\ + have \take_bit n k < 0\ + by (rule le_less_trans) + then show False + by simp + qed +next + assume ?Q + then show ?P + by (simp add: take_bit_eq_mod zmod_le_nonneg_dividend) +qed + +lemma take_bit_int_less_self_iff: + \take_bit n k < k \ 2 ^ n \ k\ + for k :: int + by (auto simp add: less_le take_bit_int_less_eq_self_iff take_bit_int_eq_self_iff + intro: order_trans [of 0 \2 ^ n\ k]) + +lemma take_bit_int_greater_self_iff: + \k < take_bit n k \ k < 0\ + for k :: int + using take_bit_int_less_eq_self_iff [of n k] by auto + +lemma take_bit_int_greater_eq_self_iff: + \k \ take_bit n k \ k < 2 ^ n\ + for k :: int + by (auto simp add: le_less take_bit_int_greater_self_iff take_bit_int_eq_self_iff + dest: sym not_sym intro: less_trans [of k 0 \2 ^ n\]) + +lemma not_exp_less_eq_0_int [simp]: + \\ 2 ^ n \ (0::int)\ + by (simp add: power_le_zero_eq) + +lemma half_nonnegative_int_iff [simp]: + \k div 2 \ 0 \ k \ 0\ for k :: int +proof (cases \k \ 0\) + case True + then show ?thesis + by (auto simp add: divide_int_def sgn_1_pos) +next + case False + then show ?thesis + by (auto simp add: divide_int_def not_le elim!: evenE) +qed + +lemma half_negative_int_iff [simp]: + \k div 2 < 0 \ k < 0\ for k :: int + by (subst Not_eq_iff [symmetric]) (simp add: not_less) + +lemma int_bit_bound: + fixes k :: int + obtains n where \\m. n \ m \ bit k m \ bit k n\ + and \n > 0 \ bit k (n - 1) \ bit k n\ +proof - + obtain q where *: \\m. q \ m \ bit k m \ bit k q\ + proof (cases \k \ 0\) + case True + moreover from power_gt_expt [of 2 \nat k\] + have \nat k < 2 ^ nat k\ + by simp + then have \int (nat k) < int (2 ^ nat k)\ + by (simp only: of_nat_less_iff) + ultimately have *: \k div 2 ^ nat k = 0\ + by simp + show thesis + proof (rule that [of \nat k\]) + fix m + assume \nat k \ m\ + then show \bit k m \ bit k (nat k)\ + by (auto simp add: * bit_iff_odd power_add zdiv_zmult2_eq dest!: le_Suc_ex) + qed + next + case False + moreover from power_gt_expt [of 2 \nat (- k)\] + have \nat (- k) < 2 ^ nat (- k)\ + by simp + then have \int (nat (- k)) < int (2 ^ nat (- k))\ + by (simp only: of_nat_less_iff) + ultimately have \- k div - (2 ^ nat (- k)) = - 1\ + by (subst div_pos_neg_trivial) simp_all + then have *: \k div 2 ^ nat (- k) = - 1\ + by simp + show thesis + proof (rule that [of \nat (- k)\]) + fix m + assume \nat (- k) \ m\ + then show \bit k m \ bit k (nat (- k))\ + by (auto simp add: * bit_iff_odd power_add zdiv_zmult2_eq minus_1_div_exp_eq_int dest!: le_Suc_ex) + qed + qed + show thesis + proof (cases \\m. bit k m \ bit k q\) + case True + then have \bit k 0 \ bit k q\ + by blast + with True that [of 0] show thesis + by simp + next + case False + then obtain r where **: \bit k r \ bit k q\ + by blast + have \r < q\ + by (rule ccontr) (use * [of r] ** in simp) + define N where \N = {n. n < q \ bit k n \ bit k q}\ + moreover have \finite N\ \r \ N\ + using ** N_def \r < q\ by auto + moreover define n where \n = Suc (Max N)\ + ultimately have \\m. n \ m \ bit k m \ bit k n\ + apply auto + apply (metis (full_types, lifting) "*" Max_ge_iff Suc_n_not_le_n \finite N\ all_not_in_conv mem_Collect_eq not_le) + apply (metis "*" Max_ge Suc_n_not_le_n \finite N\ linorder_not_less mem_Collect_eq) + apply (metis "*" Max_ge Suc_n_not_le_n \finite N\ linorder_not_less mem_Collect_eq) + apply (metis (full_types, lifting) "*" Max_ge_iff Suc_n_not_le_n \finite N\ all_not_in_conv mem_Collect_eq not_le) + done + have \bit k (Max N) \ bit k n\ + by (metis (mono_tags, lifting) "*" Max_in N_def \\m. n \ m \ bit k m = bit k n\ \finite N\ \r \ N\ empty_iff le_cases mem_Collect_eq) + show thesis apply (rule that [of n]) + using \\m. n \ m \ bit k m = bit k n\ apply blast + using \bit k (Max N) \ bit k n\ n_def by auto + qed +qed + +lemma take_bit_tightened_less_eq_int: + \take_bit m k \ take_bit n k\ if \m \ n\ for k :: int +proof - + have \take_bit m (take_bit n k) \ take_bit n k\ + by (simp only: take_bit_int_less_eq_self_iff take_bit_nonnegative) + with that show ?thesis + by simp +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_simps]: + \bit (of_int k) n \ possible_bit TYPE('a) n \ bit k n\ +proof (cases \possible_bit TYPE('a) n\) + case False + then show ?thesis + by (simp add: impossible_bit) +next + case True + 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] Bit_Operations.bit_double_iff [of k n] + by (cases n) (auto simp add: ac_simps possible_bit_def 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 Bit_Operations.bit_Suc possible_bit_def dest: mult_not_zero) + qed + with True 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 Bit_Operations.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 Bit_Operations.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 Bit_Operations.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 Bit_Operations.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_not_numeral: + \of_int (NOT (numeral k)) = NOT (numeral k)\ + by (simp add: local.of_int_not_eq) + +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 \Instance \<^typ>\nat\\ @@ -2139,24 +2443,15 @@ lemma and_nat_rec: \m AND n = of_bool (odd m \ odd n) + 2 * ((m div 2) AND (n div 2))\ for m n :: nat - apply (simp add: and_nat_def and_int_rec [of \int m\ \int n\] zdiv_int nat_add_distrib nat_mult_distrib) - apply (subst nat_add_distrib) - apply auto - done + by (simp add: and_nat_def and_int_rec [of \int m\ \int n\] zdiv_int nat_add_distrib nat_mult_distrib) lemma or_nat_rec: \m OR n = of_bool (odd m \ odd n) + 2 * ((m div 2) OR (n div 2))\ for m n :: nat - apply (simp add: or_nat_def or_int_rec [of \int m\ \int n\] zdiv_int nat_add_distrib nat_mult_distrib) - apply (subst nat_add_distrib) - apply auto - done + by (simp add: or_nat_def or_int_rec [of \int m\ \int n\] zdiv_int nat_add_distrib nat_mult_distrib) lemma xor_nat_rec: \m XOR n = of_bool (odd m \ odd n) + 2 * ((m div 2) XOR (n div 2))\ for m n :: nat - apply (simp add: xor_nat_def xor_int_rec [of \int m\ \int n\] zdiv_int nat_add_distrib nat_mult_distrib) - apply (subst nat_add_distrib) - apply auto - done + by (simp add: xor_nat_def xor_int_rec [of \int m\ \int n\] zdiv_int nat_add_distrib nat_mult_distrib) lemma Suc_0_and_eq [simp]: \Suc 0 AND n = n mod 2\ @@ -2202,6 +2497,92 @@ \unset_bit (Suc n) m = m mod 2 + 2 * unset_bit n (m div 2)\ for m n :: nat by (simp_all add: unset_bit_Suc) +lemma push_bit_of_Suc_0 [simp]: + \push_bit n (Suc 0) = 2 ^ n\ + using push_bit_of_1 [where ?'a = nat] by simp + +lemma take_bit_of_Suc_0 [simp]: + \take_bit n (Suc 0) = of_bool (0 < n)\ + using take_bit_of_1 [where ?'a = nat] by simp + +lemma drop_bit_of_Suc_0 [simp]: + \drop_bit n (Suc 0) = of_bool (n = 0)\ + using drop_bit_of_1 [where ?'a = nat] by simp + +lemma Suc_mask_eq_exp: + \Suc (mask n) = 2 ^ n\ + by (simp add: mask_eq_exp_minus_1) + +lemma less_eq_mask: + \n \ mask n\ + by (simp add: mask_eq_exp_minus_1 le_diff_conv2) + (metis Suc_mask_eq_exp diff_Suc_1 diff_le_diff_pow diff_zero le_refl not_less_eq_eq power_0) + +lemma less_mask: + \n < mask n\ if \Suc 0 < n\ +proof - + define m where \m = n - 2\ + with that have *: \n = m + 2\ + by simp + have \Suc (Suc (Suc m)) < 4 * 2 ^ m\ + by (induction m) simp_all + then have \Suc (m + 2) < Suc (mask (m + 2))\ + by (simp add: Suc_mask_eq_exp) + then have \m + 2 < mask (m + 2)\ + by (simp add: less_le) + with * show ?thesis + by simp +qed + +lemma mask_nat_less_exp [simp]: + \(mask n :: nat) < 2 ^ n\ + by (simp add: mask_eq_exp_minus_1) + +lemma mask_nat_positive_iff [simp]: + \(0::nat) < mask n \ 0 < n\ +proof (cases \n = 0\) + case True + then show ?thesis + by simp +next + case False + then have \0 < n\ + by simp + then have \(0::nat) < mask n\ + using less_eq_mask [of n] by (rule order_less_le_trans) + with \0 < n\ show ?thesis + by simp +qed + +lemma take_bit_tightened_less_eq_nat: + \take_bit m q \ take_bit n q\ if \m \ n\ for q :: nat +proof - + have \take_bit m (take_bit n q) \ take_bit n q\ + by (rule take_bit_nat_less_eq_self) + with that show ?thesis + 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\ + using that by (simp add: take_bit_eq_mod nat_mod_distrib nat_power_eq) + context semiring_bit_operations begin @@ -2223,6 +2604,31 @@ end +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) + +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 + +lemma nat_mask_eq: + \nat (mask n) = mask n\ + by (simp add: nat_eq_iff of_nat_mask_eq) + subsection \Common algebraic structure\ @@ -2238,10 +2644,6 @@ \take_bit n 2 = of_bool (2 \ n) * 2\ using take_bit_of_exp [of n 1] by simp -lemma take_bit_of_mask: - \take_bit m (2 ^ n - 1) = 2 ^ min m n - 1\ - by (simp add: take_bit_eq_mod mask_mod_exp) - lemma push_bit_eq_0_iff [simp]: "push_bit n a = 0 \ a = 0" by (simp add: push_bit_eq_mult) @@ -2274,11 +2676,11 @@ \take_bit (Suc n) 1 = 1\ by (simp add: take_bit_Suc) -lemma take_bit_Suc_bit0 [simp]: +lemma take_bit_Suc_bit0: \take_bit (Suc n) (numeral (Num.Bit0 k)) = take_bit n (numeral k) * 2\ by (simp add: take_bit_Suc numeral_Bit0_div_2) -lemma take_bit_Suc_bit1 [simp]: +lemma take_bit_Suc_bit1: \take_bit (Suc n) (numeral (Num.Bit1 k)) = take_bit n (numeral k) * 2 + 1\ by (simp add: take_bit_Suc numeral_Bit1_div_2 mod_2_eq_odd) @@ -2286,11 +2688,11 @@ \take_bit (numeral l) 1 = 1\ by (simp add: take_bit_rec [of \numeral l\ 1]) -lemma take_bit_numeral_bit0 [simp]: +lemma take_bit_numeral_bit0: \take_bit (numeral l) (numeral (Num.Bit0 k)) = take_bit (pred_numeral l) (numeral k) * 2\ by (simp add: take_bit_rec numeral_Bit0_div_2) -lemma take_bit_numeral_bit1 [simp]: +lemma take_bit_numeral_bit1: \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) @@ -2354,21 +2756,21 @@ \drop_bit (numeral l) (- numeral (Num.Bit1 k)) = drop_bit (pred_numeral l) (- numeral (Num.inc k) :: int)\ by (simp add: numeral_eq_Suc numeral_Bit1_div_2) -lemma take_bit_Suc_minus_bit0 [simp]: +lemma take_bit_Suc_minus_bit0: \take_bit (Suc n) (- numeral (Num.Bit0 k)) = take_bit n (- numeral k) * (2 :: int)\ by (simp add: take_bit_Suc numeral_Bit0_div_2) -lemma take_bit_Suc_minus_bit1 [simp]: +lemma take_bit_Suc_minus_bit1: \take_bit (Suc n) (- numeral (Num.Bit1 k)) = take_bit n (- numeral (Num.inc k)) * 2 + (1 :: int)\ by (simp add: take_bit_Suc numeral_Bit1_div_2 add_One) -lemma take_bit_numeral_minus_bit0 [simp]: +lemma take_bit_numeral_minus_bit0: \take_bit (numeral l) (- numeral (Num.Bit0 k)) = take_bit (pred_numeral l) (- numeral k) * (2 :: int)\ - by (simp add: numeral_eq_Suc numeral_Bit0_div_2) - -lemma take_bit_numeral_minus_bit1 [simp]: + by (simp add: numeral_eq_Suc numeral_Bit0_div_2 take_bit_Suc_minus_bit0) + +lemma take_bit_numeral_minus_bit1: \take_bit (numeral l) (- numeral (Num.Bit1 k)) = take_bit (pred_numeral l) (- numeral (Num.inc k)) * 2 + (1 :: int)\ - by (simp add: numeral_eq_Suc numeral_Bit1_div_2) + by (simp add: numeral_eq_Suc numeral_Bit1_div_2 take_bit_Suc_minus_bit1) subsection \Symbolic computations on numeral expressions\ @@ -2569,6 +2971,14 @@ \bit (- numeral (num.Bit1 w) :: int) (numeral n) \ \ bit (numeral w :: int) (pred_numeral n)\ by (simp_all add: bit_minus_iff bit_not_iff numeral_eq_Suc bit_Suc add_One sub_inc_One_eq) +lemma bit_minus_numeral_Bit0_Suc_iff [simp]: + \bit (- numeral (num.Bit0 w) :: int) (Suc n) \ bit (- numeral w :: int) n\ + by (simp add: bit_Suc) + +lemma bit_minus_numeral_Bit1_Suc_iff [simp]: + \bit (- numeral (num.Bit1 w) :: int) (Suc n) \ \ bit (numeral w :: int) n\ + by (simp add: bit_Suc add_One flip: bit_not_int_iff) + lemma and_not_numerals: \1 AND NOT 1 = (0 :: int)\ \1 AND NOT (numeral (Num.Bit0 n)) = (1 :: int)\ @@ -2684,6 +3094,91 @@ \k XOR - numeral n = NOT (k XOR (neg_numeral_class.sub n num.One))\ for k :: int by (simp_all add: minus_numeral_eq_not_sub_one) +definition take_bit_num :: \nat \ num \ num option\ + where \take_bit_num n m = + (if take_bit n (numeral m ::nat) = 0 then None else Some (num_of_nat (take_bit n (numeral m ::nat))))\ + +lemma take_bit_num_simps [code]: + \take_bit_num 0 m = None\ + \take_bit_num (Suc n) Num.One = + Some Num.One\ + \take_bit_num (Suc n) (Num.Bit0 m) = + (case take_bit_num n m of None \ None | Some q \ Some (Num.Bit0 q))\ + \take_bit_num (Suc n) (Num.Bit1 m) = + Some (case take_bit_num n m of None \ Num.One | Some q \ Num.Bit1 q)\ + by (auto simp add: take_bit_num_def ac_simps mult_2 num_of_nat_double + take_bit_Suc_bit0 take_bit_Suc_bit1) + +lemma take_bit_num_numeral_simps: + \take_bit_num (numeral n) Num.One = + Some Num.One\ + \take_bit_num (numeral n) (Num.Bit0 m) = + (case take_bit_num (pred_numeral n) m of None \ None | Some q \ Some (Num.Bit0 q))\ + \take_bit_num (numeral n) (Num.Bit1 m) = + Some (case take_bit_num (pred_numeral n) m of None \ Num.One | Some q \ Num.Bit1 q)\ + by (auto simp add: take_bit_num_def ac_simps mult_2 num_of_nat_double + take_bit_numeral_bit0 take_bit_numeral_bit1) + +context semiring_bit_operations +begin + +lemma take_bit_num_eq_None_imp: + \take_bit m (numeral n) = 0\ if \take_bit_num m n = None\ +proof - + from that have \take_bit m (numeral n :: nat) = 0\ + by (simp add: take_bit_num_def split: if_splits) + then have \of_nat (take_bit m (numeral n)) = of_nat 0\ + by simp + then show ?thesis + by (simp add: of_nat_take_bit) +qed + +lemma take_bit_num_eq_Some_imp: + \take_bit m (numeral n) = numeral q\ if \take_bit_num m n = Some q\ +proof - + from that have \take_bit m (numeral n :: nat) = numeral q\ + by (auto simp add: take_bit_num_def Num.numeral_num_of_nat_unfold split: if_splits) + then have \of_nat (take_bit m (numeral n)) = of_nat (numeral q)\ + by simp + then show ?thesis + by (simp add: of_nat_take_bit) +qed + +lemma take_bit_numeral_numeral: + \take_bit (numeral m) (numeral n) = + (case take_bit_num (numeral m) n of None \ 0 | Some q \ numeral q)\ + by (auto split: option.split dest: take_bit_num_eq_None_imp take_bit_num_eq_Some_imp) + +end + +lemma take_bit_numeral_minus_numeral_int: + \take_bit (numeral m) (- numeral n :: int) = + (case take_bit_num (numeral m) n of None \ 0 | Some q \ take_bit (numeral m) (2 ^ numeral m - numeral q))\ (is \?lhs = ?rhs\) +proof (cases \take_bit_num (numeral m) n\) + case None + then show ?thesis + by (auto dest: take_bit_num_eq_None_imp [where ?'a = int] simp add: take_bit_eq_0_iff) +next + case (Some q) + then have q: \take_bit (numeral m) (numeral n :: int) = numeral q\ + by (auto dest: take_bit_num_eq_Some_imp) + let ?T = \take_bit (numeral m) :: int \ int\ + have *: \?T (2 ^ numeral m) = ?T (?T 0)\ + by (simp add: take_bit_eq_0_iff) + have \?lhs = ?T (0 - numeral n)\ + by simp + also have \\ = ?T (?T (?T 0) - ?T (?T (numeral n)))\ + by (simp only: take_bit_diff) + also have \\ = ?T (2 ^ numeral m - ?T (numeral n))\ + by (simp only: take_bit_diff flip: *) + also have \\ = ?rhs\ + by (simp add: q Some) + finally show ?thesis . +qed + +declare take_bit_num_simps [simp] take_bit_num_numeral_simps [simp] take_bit_numeral_numeral [simp] + take_bit_numeral_minus_numeral_int [simp] + subsection \More properties\ @@ -2705,7 +3200,7 @@ moreover have \take_bit n (take_bit n (k + 1) - 1) = take_bit n k\ by (simp add: take_bit_eq_mod mod_simps) ultimately show ?P - by (simp add: take_bit_minus_one_eq_mask) + by simp qed lemma take_bit_eq_mask_iff_exp_dvd: @@ -2713,367 +3208,6 @@ for k :: int by (simp add: take_bit_eq_mask_iff flip: take_bit_eq_0_iff) -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_simps]: - \bit (of_int k) n \ possible_bit TYPE('a) n \ bit k n\ -proof (cases \possible_bit TYPE('a) n\) - case False - then show ?thesis - by (simp add: impossible_bit) -next - case True - 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] Bit_Operations.bit_double_iff [of k n] - by (cases n) (auto simp add: ac_simps possible_bit_def 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 Bit_Operations.bit_Suc possible_bit_def dest: mult_not_zero) - qed - with True 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 Bit_Operations.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 Bit_Operations.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 Bit_Operations.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 Bit_Operations.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_not_numeral: - \of_int (NOT (numeral k)) = NOT (numeral k)\ - by (simp add: local.of_int_not_eq) - -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 - -lemma take_bit_incr_eq: - \take_bit n (k + 1) = 1 + take_bit n k\ if \take_bit n k \ 2 ^ n - 1\ - for k :: int -proof - - from that have \2 ^ n \ k mod 2 ^ n + 1\ - by (simp add: take_bit_eq_mod) - moreover have \k mod 2 ^ n < 2 ^ n\ - by simp - ultimately have *: \k mod 2 ^ n + 1 < 2 ^ n\ - by linarith - have \(k + 1) mod 2 ^ n = (k mod 2 ^ n + 1) mod 2 ^ n\ - by (simp add: mod_simps) - also have \\ = k mod 2 ^ n + 1\ - using * by (simp add: zmod_trivial_iff) - finally have \(k + 1) mod 2 ^ n = k mod 2 ^ n + 1\ . - then show ?thesis - by (simp add: take_bit_eq_mod) -qed - -lemma take_bit_decr_eq: - \take_bit n (k - 1) = take_bit n k - 1\ if \take_bit n k \ 0\ - for k :: int -proof - - from that have \k mod 2 ^ n \ 0\ - by (simp add: take_bit_eq_mod) - moreover have \k mod 2 ^ n \ 0\ \k mod 2 ^ n < 2 ^ n\ - by simp_all - ultimately have *: \k mod 2 ^ n > 0\ - by linarith - have \(k - 1) mod 2 ^ n = (k mod 2 ^ n - 1) mod 2 ^ n\ - by (simp add: mod_simps) - also have \\ = k mod 2 ^ n - 1\ - by (simp add: zmod_trivial_iff) - (use \k mod 2 ^ n < 2 ^ n\ * in linarith) - finally have \(k - 1) mod 2 ^ n = k mod 2 ^ n - 1\ . - then show ?thesis - by (simp add: take_bit_eq_mod) -qed - -lemma take_bit_int_greater_eq: - \k + 2 ^ n \ take_bit n k\ if \k < 0\ for k :: int -proof - - have \k + 2 ^ n \ take_bit n (k + 2 ^ n)\ - proof (cases \k > - (2 ^ n)\) - case False - then have \k + 2 ^ n \ 0\ - by simp - also note take_bit_nonnegative - finally show ?thesis . - next - case True - with that have \0 \ k + 2 ^ n\ and \k + 2 ^ n < 2 ^ n\ - by simp_all - then show ?thesis - by (simp only: take_bit_eq_mod mod_pos_pos_trivial) - qed - then show ?thesis - by (simp add: take_bit_eq_mod) -qed - -lemma take_bit_int_less_eq: - \take_bit n k \ k - 2 ^ n\ if \2 ^ n \ k\ and \n > 0\ for k :: int - using that zmod_le_nonneg_dividend [of \k - 2 ^ n\ \2 ^ n\] - by (simp add: take_bit_eq_mod) - -lemma take_bit_int_less_eq_self_iff: - \take_bit n k \ k \ 0 \ k\ (is \?P \ ?Q\) - for k :: int -proof - assume ?P - show ?Q - proof (rule ccontr) - assume \\ 0 \ k\ - then have \k < 0\ - by simp - with \?P\ - have \take_bit n k < 0\ - by (rule le_less_trans) - then show False - by simp - qed -next - assume ?Q - then show ?P - by (simp add: take_bit_eq_mod zmod_le_nonneg_dividend) -qed - -lemma take_bit_int_less_self_iff: - \take_bit n k < k \ 2 ^ n \ k\ - for k :: int - by (auto simp add: less_le take_bit_int_less_eq_self_iff take_bit_int_eq_self_iff - intro: order_trans [of 0 \2 ^ n\ k]) - -lemma take_bit_int_greater_self_iff: - \k < take_bit n k \ k < 0\ - for k :: int - using take_bit_int_less_eq_self_iff [of n k] by auto - -lemma take_bit_int_greater_eq_self_iff: - \k \ take_bit n k \ k < 2 ^ n\ - for k :: int - by (auto simp add: le_less take_bit_int_greater_self_iff take_bit_int_eq_self_iff - dest: sym not_sym intro: less_trans [of k 0 \2 ^ n\]) - -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\ - using that by (simp add: take_bit_eq_mod nat_mod_distrib nat_power_eq) - -lemma not_exp_less_eq_0_int [simp]: - \\ 2 ^ n \ (0::int)\ - by (simp add: power_le_zero_eq) - -lemma half_nonnegative_int_iff [simp]: - \k div 2 \ 0 \ k \ 0\ for k :: int -proof (cases \k \ 0\) - case True - then show ?thesis - by (auto simp add: divide_int_def sgn_1_pos) -next - case False - then show ?thesis - by (auto simp add: divide_int_def not_le elim!: evenE) -qed - -lemma half_negative_int_iff [simp]: - \k div 2 < 0 \ k < 0\ for k :: int - by (subst Not_eq_iff [symmetric]) (simp add: not_less) - -lemma push_bit_of_Suc_0 [simp]: - "push_bit n (Suc 0) = 2 ^ n" - using push_bit_of_1 [where ?'a = nat] by simp - -lemma take_bit_of_Suc_0 [simp]: - "take_bit n (Suc 0) = of_bool (0 < n)" - using take_bit_of_1 [where ?'a = nat] by simp - -lemma drop_bit_of_Suc_0 [simp]: - "drop_bit n (Suc 0) = of_bool (n = 0)" - using drop_bit_of_1 [where ?'a = nat] by simp - -lemma int_bit_bound: - fixes k :: int - obtains n where \\m. n \ m \ bit k m \ bit k n\ - and \n > 0 \ bit k (n - 1) \ bit k n\ -proof - - obtain q where *: \\m. q \ m \ bit k m \ bit k q\ - proof (cases \k \ 0\) - case True - moreover from power_gt_expt [of 2 \nat k\] - have \nat k < 2 ^ nat k\ - by simp - then have \int (nat k) < int (2 ^ nat k)\ - by (simp only: of_nat_less_iff) - ultimately have *: \k div 2 ^ nat k = 0\ - by simp - show thesis - proof (rule that [of \nat k\]) - fix m - assume \nat k \ m\ - then show \bit k m \ bit k (nat k)\ - by (auto simp add: * bit_iff_odd power_add zdiv_zmult2_eq dest!: le_Suc_ex) - qed - next - case False - moreover from power_gt_expt [of 2 \nat (- k)\] - have \nat (- k) < 2 ^ nat (- k)\ - by simp - then have \int (nat (- k)) < int (2 ^ nat (- k))\ - by (simp only: of_nat_less_iff) - ultimately have \- k div - (2 ^ nat (- k)) = - 1\ - by (subst div_pos_neg_trivial) simp_all - then have *: \k div 2 ^ nat (- k) = - 1\ - by simp - show thesis - proof (rule that [of \nat (- k)\]) - fix m - assume \nat (- k) \ m\ - then show \bit k m \ bit k (nat (- k))\ - by (auto simp add: * bit_iff_odd power_add zdiv_zmult2_eq minus_1_div_exp_eq_int dest!: le_Suc_ex) - qed - qed - show thesis - proof (cases \\m. bit k m \ bit k q\) - case True - then have \bit k 0 \ bit k q\ - by blast - with True that [of 0] show thesis - by simp - next - case False - then obtain r where **: \bit k r \ bit k q\ - by blast - have \r < q\ - by (rule ccontr) (use * [of r] ** in simp) - define N where \N = {n. n < q \ bit k n \ bit k q}\ - moreover have \finite N\ \r \ N\ - using ** N_def \r < q\ by auto - moreover define n where \n = Suc (Max N)\ - ultimately have \\m. n \ m \ bit k m \ bit k n\ - apply auto - apply (metis (full_types, lifting) "*" Max_ge_iff Suc_n_not_le_n \finite N\ all_not_in_conv mem_Collect_eq not_le) - apply (metis "*" Max_ge Suc_n_not_le_n \finite N\ linorder_not_less mem_Collect_eq) - apply (metis "*" Max_ge Suc_n_not_le_n \finite N\ linorder_not_less mem_Collect_eq) - apply (metis (full_types, lifting) "*" Max_ge_iff Suc_n_not_le_n \finite N\ all_not_in_conv mem_Collect_eq not_le) - done - have \bit k (Max N) \ bit k n\ - by (metis (mono_tags, lifting) "*" Max_in N_def \\m. n \ m \ bit k m = bit k n\ \finite N\ \r \ N\ empty_iff le_cases mem_Collect_eq) - show thesis apply (rule that [of n]) - using \\m. n \ m \ bit k m = bit k n\ apply blast - using \bit k (Max N) \ bit k n\ n_def by auto - qed -qed - -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 - -lemma Suc_mask_eq_exp: - \Suc (mask n) = 2 ^ n\ - by (simp add: mask_eq_exp_minus_1) - -lemma less_eq_mask: - \n \ mask n\ - by (simp add: mask_eq_exp_minus_1 le_diff_conv2) - (metis Suc_mask_eq_exp diff_Suc_1 diff_le_diff_pow diff_zero le_refl not_less_eq_eq power_0) - -lemma less_mask: - \n < mask n\ if \Suc 0 < n\ -proof - - define m where \m = n - 2\ - with that have *: \n = m + 2\ - by simp - have \Suc (Suc (Suc m)) < 4 * 2 ^ m\ - by (induction m) simp_all - then have \Suc (m + 2) < Suc (mask (m + 2))\ - by (simp add: Suc_mask_eq_exp) - then have \m + 2 < mask (m + 2)\ - by (simp add: less_le) - with * show ?thesis - by simp -qed - subsection \Bit concatenation\ @@ -3203,7 +3337,7 @@ lemma signed_take_bit_of_minus_1 [simp]: \signed_take_bit n (- 1) = - 1\ - by (simp add: signed_take_bit_def take_bit_minus_one_eq_mask mask_eq_exp_minus_1 possible_bit_def) + by (simp add: signed_take_bit_def mask_eq_exp_minus_1 possible_bit_def) lemma signed_take_bit_Suc_1 [simp]: \signed_take_bit (Suc n) 1 = 1\ @@ -3246,7 +3380,7 @@ lemma signed_take_bit_eq_concat_bit: \signed_take_bit n k = concat_bit n k (- of_bool (bit k n))\ - by (simp add: concat_bit_def signed_take_bit_def push_bit_minus_one_eq_not_mask) + by (simp add: concat_bit_def signed_take_bit_def) lemma signed_take_bit_add: \signed_take_bit n (signed_take_bit n k + signed_take_bit n l) = signed_take_bit n (k + l)\ @@ -3449,7 +3583,8 @@ 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) + (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