# HG changeset patch # User haftmann # Date 1600336650 0 # Node ID 5193570b739a22d4403892e071fd4f4c174f4e4d # Parent d488d643e677c6be33ebe14bf03bc62120cbd655 more lemmas diff -r d488d643e677 -r 5193570b739a src/HOL/Divides.thy --- a/src/HOL/Divides.thy Tue Sep 15 08:57:47 2020 +0200 +++ b/src/HOL/Divides.thy Thu Sep 17 09:57:30 2020 +0000 @@ -1251,6 +1251,87 @@ code_module Divides \ (SML) Arith and (OCaml) Arith and (Haskell) Arith +subsection \More on bit operations\ + +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_trival_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_trival_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_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\]) + + subsection \Lemmas of doubtful value\ lemma div_geq: "m div n = Suc ((m - n) div n)" if "0 < n" and " \ m < n" for m n :: nat diff -r d488d643e677 -r 5193570b739a src/HOL/Library/Bit_Operations.thy --- a/src/HOL/Library/Bit_Operations.thy Tue Sep 15 08:57:47 2020 +0200 +++ b/src/HOL/Library/Bit_Operations.thy Thu Sep 17 09:57:30 2020 +0000 @@ -1106,23 +1106,45 @@ for k :: int by (simp add: signed_take_bit_def not_less concat_bit_def) -lemma signed_take_bit_greater_eq: +lemma signed_take_bit_int_eq_self_iff: + \signed_take_bit n k = k \ - (2 ^ n) \ k \ k < 2 ^ n\ + for k :: int + by (auto simp add: signed_take_bit_eq_take_bit_shift take_bit_int_eq_self_iff algebra_simps) + +lemma signed_take_bit_int_less_eq_self_iff: + \signed_take_bit n k \ k \ - (2 ^ n) \ k\ + for k :: int + by (simp add: signed_take_bit_eq_take_bit_shift take_bit_int_less_eq_self_iff algebra_simps) + linarith + +lemma signed_take_bit_int_less_self_iff: + \signed_take_bit n k < k \ 2 ^ n \ k\ + for k :: int + by (simp add: signed_take_bit_eq_take_bit_shift take_bit_int_less_self_iff algebra_simps) + +lemma signed_take_bit_int_greater_self_iff: + \k < signed_take_bit n k \ k < - (2 ^ n)\ + for k :: int + by (simp add: signed_take_bit_eq_take_bit_shift take_bit_int_greater_self_iff algebra_simps) + linarith + +lemma signed_take_bit_int_greater_eq_self_iff: + \k \ signed_take_bit n k \ k < 2 ^ n\ + for k :: int + by (simp add: signed_take_bit_eq_take_bit_shift take_bit_int_greater_eq_self_iff algebra_simps) + +lemma signed_take_bit_int_greater_eq: \k + 2 ^ Suc n \ signed_take_bit n k\ if \k < - (2 ^ n)\ for k :: int using that take_bit_greater_eq [of \k + 2 ^ n\ \Suc n\] by (simp add: signed_take_bit_eq_take_bit_shift) -lemma signed_take_bit_less_eq: +lemma signed_take_bit_int_less_eq: \signed_take_bit n k \ k - 2 ^ Suc n\ if \k \ 2 ^ n\ for k :: int using that take_bit_less_eq [of \Suc n\ \k + 2 ^ n\] by (simp add: signed_take_bit_eq_take_bit_shift) -lemma signed_take_bit_eq_self: - \signed_take_bit n k = k\ if \- (2 ^ n) \ k\ \k < 2 ^ n\ - for k :: int - using that by (simp add: signed_take_bit_eq_take_bit_shift take_bit_int_eq_self) - lemma signed_take_bit_Suc_bit0 [simp]: \signed_take_bit (Suc n) (numeral (Num.Bit0 k)) = signed_take_bit n (numeral k) * (2 :: int)\ by (simp add: signed_take_bit_Suc) diff -r d488d643e677 -r 5193570b739a src/HOL/Parity.thy --- a/src/HOL/Parity.thy Tue Sep 15 08:57:47 2020 +0200 +++ b/src/HOL/Parity.thy Thu Sep 17 09:57:30 2020 +0000 @@ -1024,6 +1024,37 @@ qed qed +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 lemma nat_bit_induct [case_names zero even odd]: @@ -1147,7 +1178,7 @@ also have "\ = - int (2 * n) - 1" by (simp add: algebra_simps) finally show ?case - using even by simp + using even.prems by simp next case (odd n) have "P (- int (Suc n) * 2)" @@ -1155,7 +1186,7 @@ also have "\ = - int (Suc (2 * n)) - 1" by (simp add: algebra_simps) finally show ?case - using odd by simp + using odd.prems by simp qed qed @@ -1584,6 +1615,56 @@ \bit (push_bit m k) n \ m \ n \ bit k (n - m)\ for k :: int by (auto simp add: bit_push_bit_iff) +lemma take_bit_nat_less_exp: + \take_bit n m < 2 ^ n\ for n m ::nat + by (simp add: take_bit_eq_mod) + +lemma take_bit_nat_eq_self_iff: + \take_bit n m = m \ m < 2 ^ n\ (is \?P \ ?Q\) + for n m :: nat +proof + assume ?P + moreover note take_bit_nat_less_exp [of n m] + ultimately show ?Q + by simp +next + assume ?Q + then show ?P + by (simp add: take_bit_eq_mod) +qed + +lemma take_bit_nat_less_eq_self: + \take_bit n m \ m\ for n m :: nat + by (simp add: take_bit_eq_mod) + +lemma take_bit_nonnegative [simp]: + \take_bit n k \ 0\ + for k :: int + by (simp add: take_bit_eq_mod) + +lemma not_take_bit_negative [simp]: + \\ take_bit n k < 0\ + for k :: int + by (simp add: not_less) + +lemma take_bit_int_less_exp: + \take_bit n k < 2 ^ n\ for k :: int + by (simp add: take_bit_eq_mod) + +lemma take_bit_int_eq_self_iff: + \take_bit n k = k \ 0 \ k \ k < 2 ^ n\ (is \?P \ ?Q\) + for k :: int +proof + assume ?P + moreover note take_bit_int_less_exp [of n k] take_bit_nonnegative [of n k] + ultimately show ?Q + by simp +next + assume ?Q + then show ?P + by (simp add: take_bit_eq_mod) +qed + class unique_euclidean_semiring_with_bit_shifts = unique_euclidean_semiring_with_nat + semiring_bit_shifts begin @@ -1752,10 +1833,6 @@ "drop_bit n (Suc 0) = of_bool (n = 0)" using drop_bit_of_1 [where ?'a = nat] by simp -lemma take_bit_eq_self: - \take_bit n m = m\ if \m < 2 ^ n\ for n m :: nat - using that by (simp add: take_bit_eq_mod) - lemma push_bit_minus_one: "push_bit n (- 1 :: int) = - (2 ^ n)" by (simp add: push_bit_eq_mult) @@ -1782,24 +1859,6 @@ for k l :: int by (simp add: take_bit_eq_mod mod_diff_eq) -lemma take_bit_nonnegative [simp]: - \take_bit n k \ 0\ - for k :: int - by (simp add: take_bit_eq_mod) - -lemma not_take_bit_negative [simp]: - \\ take_bit n k < 0\ - for k :: int - by (simp add: not_less) - -lemma take_bit_int_less_exp: - \take_bit n k < 2 ^ n\ for k :: int - by (simp add: take_bit_eq_mod) - -lemma take_bit_int_eq_self: - \take_bit n k = k\ if \0 \ k\ \k < 2 ^ n\ for k :: int - using that by (simp add: take_bit_eq_mod) - lemma bit_imp_take_bit_positive: \0 < take_bit m k\ if \n < m\ and \bit k n\ for k :: int proof (rule ccontr) diff -r d488d643e677 -r 5193570b739a src/HOL/Word/Bits_Int.thy --- a/src/HOL/Word/Bits_Int.thy Tue Sep 15 08:57:47 2020 +0200 +++ b/src/HOL/Word/Bits_Int.thy Thu Sep 17 09:57:30 2020 +0000 @@ -372,11 +372,11 @@ lemma sbintrunc_inc: \k + 2 ^ Suc n \ sbintrunc n k\ if \k < - (2 ^ n)\ - using that by (fact signed_take_bit_greater_eq) + using that by (fact signed_take_bit_int_greater_eq) lemma sbintrunc_dec: \sbintrunc n k \ k - 2 ^ (Suc n)\ if \k \ 2 ^ n\ - using that by (fact signed_take_bit_less_eq) + using that by (fact signed_take_bit_int_less_eq) lemma bintr_ge0: "0 \ bintrunc n w" by (simp add: bintrunc_mod2p) diff -r d488d643e677 -r 5193570b739a src/HOL/Word/Conversions.thy --- a/src/HOL/Word/Conversions.thy Tue Sep 15 08:57:47 2020 +0200 +++ b/src/HOL/Word/Conversions.thy Thu Sep 17 09:57:30 2020 +0000 @@ -455,7 +455,7 @@ 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) + by (simp add: nat_take_bit_eq div_int_pos_iff nat_div_distrib take_bit_nat_eq_self_iff) qed lemma unat_mod_distrib: @@ -468,7 +468,7 @@ 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) + by (simp add: nat_take_bit_eq mod_int_pos_iff less_le nat_mod_distrib take_bit_nat_eq_self_iff) qed lemma uint_div_distrib: diff -r d488d643e677 -r 5193570b739a src/HOL/Word/Word.thy --- a/src/HOL/Word/Word.thy Tue Sep 15 08:57:47 2020 +0200 +++ b/src/HOL/Word/Word.thy Thu Sep 17 09:57:30 2020 +0000 @@ -358,7 +358,7 @@ by (auto simp add: word_greater_zero_iff of_nat_word_eq_0_iff l) moreover from \n < 2 ^ m\ have \(of_nat n :: 'a word) < 2 ^ (LENGTH('a) - 1)\ using of_nat_word_less_iff [where ?'a = 'a, of n \2 ^ m\] - by (cases \m = 0\) (simp_all add: not_less take_bit_eq_self ac_simps l) + by (simp add: l take_bit_eq_mod) ultimately have \P (2 * of_nat n)\ by (rule word_even) then show ?case @@ -371,7 +371,7 @@ by simp moreover from \Suc n \ 2 ^ m\ have \(of_nat n :: 'a word) < 2 ^ (LENGTH('a) - 1)\ using of_nat_word_less_iff [where ?'a = 'a, of n \2 ^ m\] - by (cases \m = 0\) (simp_all add: not_less take_bit_eq_self ac_simps l) + by (simp add: l take_bit_eq_mod) ultimately have \P (1 + 2 * of_nat n)\ by (rule word_odd) then show ?case @@ -1396,8 +1396,8 @@ "n = LENGTH('a::len) \ td_ext (unat :: 'a word \ nat) of_nat (unats n) (\i. i mod 2 ^ n)" apply (standard; transfer) - apply (simp_all add: unats_def take_bit_int_less_exp take_bit_of_nat take_bit_eq_self) - apply (simp add: take_bit_eq_mod) + apply (simp_all add: unats_def take_bit_int_less_exp take_bit_of_nat take_bit_nat_eq_self_iff + flip: take_bit_eq_mod) done lemmas unat_of_nat = td_ext_unat [THEN td_ext.eq_norm] @@ -3882,7 +3882,7 @@ by (cases \LENGTH('a)\) simp_all have *: \sint x + sint y + 2 ^ Suc n > signed_take_bit n (sint x + sint y) \ sint x + sint y \ - (2 ^ n)\ \signed_take_bit n (sint x + sint y) > sint x + sint y - 2 ^ Suc n \ 2 ^ n > sint x + sint y\ - using signed_take_bit_greater_eq [of \sint x + sint y\ n] signed_take_bit_less_eq [of n \sint x + sint y\] + using signed_take_bit_int_greater_eq [of \sint x + sint y\ n] signed_take_bit_int_less_eq [of n \sint x + sint y\] by (auto intro: ccontr) have \sint x + sint y = sint (x + y) \ (sint (x + y) < 0 \ sint x < 0) \ @@ -4433,7 +4433,7 @@ apply (subst take_bit_diff [symmetric]) apply (subst nat_take_bit_eq) apply (simp add: nat_le_eq_zle) - apply (simp add: nat_diff_distrib take_bit_eq_self less_imp_diff_less bintr_lt2p) + apply (simp add: nat_diff_distrib take_bit_nat_eq_self_iff less_imp_diff_less bintr_lt2p) done qed