# HG changeset patch # User haftmann # Date 1575306916 0 # Node ID d50a718ccf35422cd4981fde96f5452a09da4a52 # Parent 26b35a97bddb902bb06cdebb75705eda32cf2569 tuned material diff -r 26b35a97bddb -r d50a718ccf35 src/HOL/Code_Numeral.thy --- a/src/HOL/Code_Numeral.thy Mon Dec 02 18:29:22 2019 +0100 +++ b/src/HOL/Code_Numeral.thy Mon Dec 02 17:15:16 2019 +0000 @@ -297,8 +297,8 @@ is \drop_bit\ . instance by (standard; transfer) - (fact bit_eq_rec bit_induct push_bit_eq_mult drop_bit_eq_div - bits_div_0 bits_div_by_1 bit_mod_div_trivial even_succ_div_2 + (fact bit_eq_rec bits_induct push_bit_eq_mult drop_bit_eq_div + bits_div_0 bits_div_by_1 bits_mod_div_trivial even_succ_div_2 exp_div_exp_eq div_exp_eq mod_exp_eq mult_exp_mod_exp_eq div_exp_mod_exp_eq)+ end @@ -993,8 +993,8 @@ is \drop_bit\ . instance by (standard; transfer) - (fact bit_eq_rec bit_induct push_bit_eq_mult drop_bit_eq_div - bits_div_0 bits_div_by_1 bit_mod_div_trivial even_succ_div_2 + (fact bit_eq_rec bits_induct push_bit_eq_mult drop_bit_eq_div + bits_div_0 bits_div_by_1 bits_mod_div_trivial even_succ_div_2 exp_div_exp_eq div_exp_eq mod_exp_eq mult_exp_mod_exp_eq div_exp_mod_exp_eq)+ end diff -r 26b35a97bddb -r d50a718ccf35 src/HOL/Library/Type_Length.thy --- a/src/HOL/Library/Type_Length.thy Mon Dec 02 18:29:22 2019 +0100 +++ b/src/HOL/Library/Type_Length.thy Mon Dec 02 17:15:16 2019 +0000 @@ -103,4 +103,8 @@ end +lemma length_not_greater_eq_2_iff [simp]: + \\ 2 \ LENGTH('a::len) \ LENGTH('a) = 1\ + by (auto simp add: not_le dest: less_2_cases) + end diff -r 26b35a97bddb -r d50a718ccf35 src/HOL/Parity.thy --- a/src/HOL/Parity.thy Mon Dec 02 18:29:22 2019 +0100 +++ b/src/HOL/Parity.thy Mon Dec 02 17:15:16 2019 +0000 @@ -569,13 +569,13 @@ subsection \Abstract bit structures\ class semiring_bits = semiring_parity + - assumes bit_induct [case_names stable rec]: + assumes bits_induct [case_names stable rec]: \(\a. a div 2 = a \ P a) \ (\a b. P a \ (of_bool b + 2 * a) div 2 = a \ P (of_bool b + 2 * a)) \ P a\ assumes bits_div_0 [simp]: \0 div a = 0\ and bits_div_by_1 [simp]: \a div 1 = a\ - and bit_mod_div_trivial [simp]: \a mod b div b = 0\ + and bits_mod_div_trivial [simp]: \a mod b div b = 0\ and even_succ_div_2 [simp]: \even a \ (1 + a) div 2 = a div 2\ and exp_div_exp_eq: \2 ^ m div 2 ^ n = of_bool (2 ^ m \ 0 \ m \ n) * 2 ^ (m - n)\ and div_exp_eq: \a div 2 ^ m div 2 ^ n = a div 2 ^ (m + n)\ @@ -584,6 +584,10 @@ and div_exp_mod_exp_eq: \a div 2 ^ n mod 2 ^ m = a mod (2 ^ (n + m)) div 2 ^ n\ begin +lemma bits_div_by_0 [simp]: + \a div 0 = 0\ + by (metis add_cancel_right_right bits_mod_div_trivial mod_mult_div_eq mult_not_zero) + lemma bits_1_div_2 [simp]: \1 div 2 = 0\ using even_succ_div_2 [of 0] by simp @@ -629,7 +633,7 @@ \0 mod a = 0\ using div_mult_mod_eq [of 0 a] by simp -lemma one_mod_two_eq_one [simp]: +lemma bits_one_mod_two_eq_one [simp]: \1 mod 2 = 1\ by (simp add: mod2_eq_if) @@ -644,12 +648,16 @@ \bit a (Suc n) \ bit (a div 2) n\ using div_exp_eq [of a 1 n] by (simp add: bit_def) +lemma bit_0_eq [simp]: + \bit 0 = bot\ + by (simp add: fun_eq_iff bit_def) + context fixes a assumes stable: \a div 2 = a\ begin -lemma stable_imp_add_self: +lemma bits_stable_imp_add_self: \a + a mod 2 = 0\ proof - have \a div 2 * 2 + a mod 2 = a\ @@ -668,7 +676,7 @@ lemma bit_iff_idd_imp_stable: \a div 2 = a\ if \\n. bit a n \ odd a\ -using that proof (induction a rule: bit_induct) +using that proof (induction a rule: bits_induct) case (stable a) then show ?case by simp @@ -693,7 +701,7 @@ lemma bit_eqI: \a = b\ if \\n. bit a n \ bit b n\ -using that proof (induction a arbitrary: b rule: bit_induct) +using that proof (induction a arbitrary: b rule: bits_induct) case (stable a) from stable(2) [of 0] have **: \even b \ even a\ by simp @@ -714,7 +722,7 @@ then have \a + a mod 2 + b = b + b mod 2 + a\ by (simp add: ac_simps) with \a div 2 = a\ \b div 2 = b\ show ?case - by (simp add: stable_imp_add_self) + by (simp add: bits_stable_imp_add_self) next case (rec a p) from rec.prems [of 0] have [simp]: \p = odd b\ @@ -952,7 +960,7 @@ differently wrt. code generation. \ -lemma bit_ident: +lemma bits_ident: "push_bit n (drop_bit n a) + take_bit n a = a" using div_mult_mod_eq by (simp add: push_bit_eq_mult take_bit_eq_mod drop_bit_eq_div) @@ -1228,4 +1236,27 @@ "push_bit n (- 1 :: int) = - (2 ^ n)" by (simp add: push_bit_eq_mult) +lemma minus_1_div_exp_eq_int: + \- 1 div (2 :: int) ^ n = - 1\ + by (induction n) (use div_exp_eq [symmetric, of \- 1 :: int\ 1] in \simp_all add: ac_simps\) + +lemma drop_bit_minus_one [simp]: + \drop_bit n (- 1 :: int) = - 1\ + by (simp add: drop_bit_eq_div minus_1_div_exp_eq_int) + +lemma take_bit_uminus: + "take_bit n (- (take_bit n k)) = take_bit n (- k)" + for k :: int + by (simp add: take_bit_eq_mod mod_minus_eq) + +lemma take_bit_minus: + "take_bit n (take_bit n k - take_bit n l) = take_bit n (k - l)" + 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) + end diff -r 26b35a97bddb -r d50a718ccf35 src/HOL/ex/Bit_Operations.thy --- a/src/HOL/ex/Bit_Operations.thy Mon Dec 02 18:29:22 2019 +0100 +++ b/src/HOL/ex/Bit_Operations.thy Mon Dec 02 17:15:16 2019 +0000 @@ -9,22 +9,9 @@ Main begin -lemma minus_1_div_exp_eq_int [simp]: - \- 1 div (2 :: int) ^ n = - 1\ - for n :: nat - by (induction n) (use div_exp_eq [symmetric, of \- 1 :: int\ 1] in \simp_all add: ac_simps\) - context semiring_bits begin -lemma bits_div_by_0 [simp]: - \a div 0 = 0\ - by (metis local.add_cancel_right_right local.bit_mod_div_trivial local.mod_mult_div_eq local.mult_not_zero) - -lemma bit_0_eq [simp]: - \bit 0 = bot\ - by (simp add: fun_eq_iff bit_def) - end context semiring_bit_shifts @@ -50,7 +37,6 @@ For the sake of code generation the operations \<^const>\and\, \<^const>\or\ and \<^const>\xor\ are specified as definitional class operations. - \ definition map_bit :: \nat \ (bool \ bool) \ 'a \ 'a\ @@ -712,7 +698,6 @@ by (induction n arbitrary: k) (simp_all add: not_int_def flip: complement_div_2) - instance proof fix k l :: int and n :: nat show \bit (k AND l) n \ bit k n \ bit l n\ @@ -745,7 +730,7 @@ with xor_int.rec [of k l] show ?case by simp qed -qed (simp_all add: bit_not_iff_int) +qed (simp_all add: minus_1_div_exp_eq_int bit_not_iff_int) end @@ -774,27 +759,32 @@ using one_xor_int_eq [of k] by (simp add: ac_simps) lemma take_bit_complement_iff: - "Parity.take_bit n (complement k) = Parity.take_bit n (complement l) \ Parity.take_bit n k = Parity.take_bit n l" + "take_bit n (complement k) = take_bit n (complement l) \ take_bit n k = take_bit n l" for k l :: int - by (simp add: Parity.take_bit_eq_mod mod_eq_dvd_iff dvd_diff_commute) + by (simp add: take_bit_eq_mod mod_eq_dvd_iff dvd_diff_commute) lemma take_bit_not_iff: - "Parity.take_bit n (NOT k) = Parity.take_bit n (NOT l) \ Parity.take_bit n k = Parity.take_bit n l" + "take_bit n (NOT k) = take_bit n (NOT l) \ take_bit n k = take_bit n l" for k l :: int by (auto simp add: bit_eq_iff bit_take_bit_iff bit_not_iff_int) +lemma take_bit_not_take_bit: + \take_bit n (NOT (take_bit n k)) = take_bit n (NOT k)\ + for k :: int + by (auto simp add: bit_eq_iff bit_take_bit_iff bit_not_iff) + lemma take_bit_and [simp]: - "Parity.take_bit n (k AND l) = Parity.take_bit n k AND Parity.take_bit n l" + "take_bit n (k AND l) = take_bit n k AND take_bit n l" for k l :: int by (auto simp add: bit_eq_iff bit_take_bit_iff bit_and_iff) lemma take_bit_or [simp]: - "Parity.take_bit n (k OR l) = Parity.take_bit n k OR Parity.take_bit n l" + "take_bit n (k OR l) = take_bit n k OR take_bit n l" for k l :: int by (auto simp add: bit_eq_iff bit_take_bit_iff bit_or_iff) lemma take_bit_xor [simp]: - "Parity.take_bit n (k XOR l) = Parity.take_bit n k XOR Parity.take_bit n l" + "take_bit n (k XOR l) = take_bit n k XOR take_bit n l" for k l :: int by (auto simp add: bit_eq_iff bit_take_bit_iff bit_xor_iff) diff -r 26b35a97bddb -r d50a718ccf35 src/HOL/ex/Word.thy --- a/src/HOL/ex/Word.thy Mon Dec 02 18:29:22 2019 +0100 +++ b/src/HOL/ex/Word.thy Mon Dec 02 17:15:16 2019 +0000 @@ -10,37 +10,8 @@ "HOL-ex.Bit_Operations" begin -context - includes lifting_syntax -begin - -lemma transfer_rule_of_bool: - \((\) ===> (\)) of_bool of_bool\ - if [transfer_rule]: \0 \ 0\ \1 \ 1\ - for R :: \'a::zero_neq_one \ 'b::zero_neq_one \ bool\ (infix \\\ 50) - by (unfold of_bool_def [abs_def]) transfer_prover - -end - - subsection \Preliminaries\ -lemma length_not_greater_eq_2_iff [simp]: - \\ 2 \ LENGTH('a::len) \ LENGTH('a) = 1\ - by (auto simp add: not_le dest: less_2_cases) - -lemma take_bit_uminus: - "take_bit n (- (take_bit n k)) = take_bit n (- k)" for k :: int - by (simp add: take_bit_eq_mod mod_minus_eq) - -lemma take_bit_minus: - "take_bit n (take_bit n k - take_bit n l) = take_bit n (k - l)" 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) - definition signed_take_bit :: "nat \ int \ int" where signed_take_bit_eq_take_bit: "signed_take_bit n k = take_bit (Suc n) (k + 2 ^ n) - 2 ^ n" @@ -296,27 +267,6 @@ subsubsection \Properties\ -lemma length_cases: \ \TODO get rid of\ - obtains (triv) "LENGTH('a::len) = 1" "take_bit LENGTH('a) 2 = (0 :: int)" - | (take_bit_2) "take_bit LENGTH('a) 2 = (2 :: int)" -proof (cases "LENGTH('a) \ 2") - case False - then have "LENGTH('a) = 1" - by (auto simp add: not_le dest: less_2_cases) - then have "take_bit LENGTH('a) 2 = (0 :: int)" - by simp - with \LENGTH('a) = 1\ triv show ?thesis - by simp -next - case True - then obtain n where "LENGTH('a) = Suc (Suc n)" - by (auto dest: le_Suc_ex) - then have "take_bit LENGTH('a) 2 = (2 :: int)" - by simp - with take_bit_2 show ?thesis - by simp -qed - subsubsection \Division\ @@ -343,10 +293,6 @@ \a div 0 = 0\ for a :: \'a::len0 word\ by transfer simp -(*lemma - \a div a = of_bool (a \ 0)\ for a :: \'a::len word\ - by transfer simp*) - context includes lifting_syntax begin @@ -406,17 +352,12 @@ by transfer simp show even_iff_mod_2_eq_0: "2 dvd a \ a mod 2 = 0" for a :: "'a word" - by (transfer; cases rule: length_cases [where ?'a = 'a]) (simp_all add: mod_2_eq_odd) + by transfer (simp_all add: mod_2_eq_odd) show "\ 2 dvd a \ a mod 2 = 1" for a :: "'a word" - by (transfer; cases rule: length_cases [where ?'a = 'a]) (simp_all add: mod_2_eq_odd) + by transfer (simp_all add: mod_2_eq_odd) qed -(*lemma - \2 ^ n = (0 :: 'a word) \ LENGTH('a::len) \ n\ - apply transfer*) - - subsubsection \Orderings\ @@ -544,14 +485,14 @@ \(of_bool b + a * 2) div 2 = a\ if \a < 2 ^ (LENGTH('a) - Suc 0)\ for a :: \'a::len word\ -proof (cases rule: length_cases [where ?'a = 'a]) - case triv +proof (cases \2 \ LENGTH('a::len)\) + case False have \of_bool (odd k) < (1 :: int) \ even k\ for k :: int by auto - with triv that show ?thesis + with False that show ?thesis by (auto; transfer) simp_all next - case take_bit_2 + case True obtain n where length: \LENGTH('a) = Suc n\ by (cases \LENGTH('a)\) simp_all show ?thesis proof (cases b) @@ -567,7 +508,7 @@ by (simp add: take_bit_eq_mod divmod_digit_0) ultimately have \take_bit LENGTH('a) (k * 2) = take_bit LENGTH('a) k * 2\ by (simp add: take_bit_eq_mod) - with take_bit_2 show \take_bit LENGTH('a) (take_bit LENGTH('a) (k * 2) div take_bit LENGTH('a) 2) + with True show \take_bit LENGTH('a) (take_bit LENGTH('a) (k * 2) div take_bit LENGTH('a) 2) = take_bit LENGTH('a) k\ by simp qed @@ -586,9 +527,9 @@ by (simp add: take_bit_eq_mod divmod_digit_0) ultimately have \take_bit LENGTH('a) (1 + k * 2) = 1 + take_bit LENGTH('a) k * 2\ by (simp add: take_bit_eq_mod) - with take_bit_2 show \take_bit LENGTH('a) (take_bit LENGTH('a) (1 + k * 2) div take_bit LENGTH('a) 2) + with True show \take_bit LENGTH('a) (take_bit LENGTH('a) (1 + k * 2) div take_bit LENGTH('a) 2) = take_bit LENGTH('a) k\ - by simp + by auto qed ultimately show ?thesis by simp @@ -651,10 +592,7 @@ done show "a mod 2 ^ m mod 2 ^ n = a mod 2 ^ min m n" for a :: "'a word" and m n :: nat - apply transfer - apply (auto simp flip: take_bit_eq_mod) - apply (simp add: ac_simps) - done + by transfer (auto simp flip: take_bit_eq_mod simp add: ac_simps) show \a * 2 ^ m mod 2 ^ n = a mod 2 ^ (n - m) * 2 ^ m\ if \m \ n\ for a :: "'a word" and m n :: nat using that apply transfer @@ -663,9 +601,7 @@ done show \a div 2 ^ n mod 2 ^ m = a mod (2 ^ (n + m)) div 2 ^ n\ for a :: "'a word" and m n :: nat - apply transfer - apply (auto simp add: not_less take_bit_drop_bit ac_simps simp flip: take_bit_eq_mod drop_bit_eq_div split: split_min_lin) - done + by transfer (auto simp add: not_less take_bit_drop_bit ac_simps simp flip: take_bit_eq_mod drop_bit_eq_div split: split_min_lin) qed context @@ -691,12 +627,12 @@ lift_definition push_bit_word :: \nat \ 'a word \ 'a word\ is push_bit proof - - show \Parity.take_bit LENGTH('a) (push_bit n k) = Parity.take_bit LENGTH('a) (push_bit n l)\ - if \Parity.take_bit LENGTH('a) k = Parity.take_bit LENGTH('a) l\ for k l :: int and n :: nat + show \take_bit LENGTH('a) (push_bit n k) = take_bit LENGTH('a) (push_bit n l)\ + if \take_bit LENGTH('a) k = take_bit LENGTH('a) l\ for k l :: int and n :: nat proof - from that - have \Parity.take_bit (LENGTH('a) - n) (Parity.take_bit LENGTH('a) k) - = Parity.take_bit (LENGTH('a) - n) (Parity.take_bit LENGTH('a) l)\ + have \take_bit (LENGTH('a) - n) (take_bit LENGTH('a) k) + = take_bit (LENGTH('a) - n) (take_bit LENGTH('a) l)\ by simp moreover have \min (LENGTH('a) - n) LENGTH('a) = LENGTH('a) - n\ by simp @@ -713,19 +649,7 @@ show \push_bit n a = a * 2 ^ n\ for n :: nat and a :: "'a word" by transfer (simp add: push_bit_eq_mult) show \drop_bit n a = a div 2 ^ n\ for n :: nat and a :: "'a word" - proof (cases \n < LENGTH('a)\) - case True - then show ?thesis - by transfer - (simp add: take_bit_eq_mod drop_bit_eq_div) - next - case False - then obtain m where n: \n = LENGTH('a) + m\ - by (auto simp add: not_less dest: le_Suc_ex) - then show ?thesis - by transfer - (simp add: take_bit_eq_mod drop_bit_eq_div power_add zdiv_zmult2_eq) - qed + by transfer (simp flip: drop_bit_eq_div add: drop_bit_take_bit) qed end @@ -752,8 +676,7 @@ instance proof fix a b :: \'a word\ and n :: nat show \even (- 1 div (2 :: 'a word) ^ n) \ (2 :: 'a word) ^ n = 0\ - by transfer - (simp flip: drop_bit_eq_div add: drop_bit_take_bit, simp add: drop_bit_eq_div) + by transfer (simp flip: drop_bit_eq_div add: drop_bit_take_bit) show \bit (NOT a) n \ (2 :: 'a word) ^ n \ 0 \ \ bit a n\ by transfer (simp add: bit_not_iff) show \bit (a AND b) n \ bit a n \ bit b n\